I want to copy several rows in a mysql table based on a foreign key, and asign the new rows a new foreign key ID. Assuming my table layout looks like this:
test
-----
table1_id int(11)
value varchar(20)
How do I accomplish this?
Found out that the query would need to look like this:
INSERT INTO test (table1_id, value) (SELECT '2', value FROM test WHERE table1_id=1)
which would copy all rows with the foreign key ID '1' and assign the new rows with ID 2 instead. If the table contains more rows you could add them or change order in the SELECT part, like this
...(SELECT row1, '{$new_id}', value, another_row FROM...
Related
i hava a table with varchar primary key, that is a foreing key for some other tables.
Something like:
ID-------------NAME
1011001020-----product 1
1011001022-----product 2
1011001025-----product 3
Then, i have this array
array(
'1011001020',
'1011001022',
'1011001025',
'x',
'y'
)
This array will be used to insert values in another table with FK, so if any value is not an ID on the first table, the INSERT query will brake.
How do i find 'x' and 'y' before any attempt to insert. I would like to avoid selecting all ids from table one and make a PHP comparison, since there are a lot of records. I would rather a MySQL approach
I would suggest the following procedure:
Create the table and insert all the values into the table.
Remove the values that do not match.
Add the foreign key constraint.
The second and third steps can be done easily in SQL:
delete from temporarytable
where tt.otherid not in (select ot.otherid from othertable ot);
alter table temporarytable
add constraint fk_othertable foreign key (otherid) references othertable(otherid);
You can load the data however you like. For speed, I would recommend load data infile.
give this a shot. Tested on server, products is the new table and inserted only rows found in the array from items table.
INSERT INTO `products` ( `name` )
SELECT `name` FROM `items` WHERE `vendor_id` IN ( 1,2,3,4,.... )
I have a SQL query as follows-
"INSERT INTO users(id, rank) SELECT v.user, v.vote FROM votes v WHERE
v.assertion = '$ID' ON DUPLICATE KEY UPDATE
rank = ( CASE WHEN v.vote = '1' THEN rank+50 WHEN v.vote = '-1'
THEN rank-200 WHEN v.vote = '3' THEN rank+100 ELSE rank END)"
applied on a database with a table users with and id and rank field, and a votes table with a user and vote field. I have to update the rank of the users in the users table based on their vote.
I really like this kind of query, but I've noticed a problem: every time I execute this from my PHP script the query adds a row to the users table completely empty (with only an ID, which is A_I, and a rank of 1, when usually there would be other field as well). I can't really wrap my head around why this happens.
Any help/idea?
Your table does not have a primary key first provide a primary key to id
run this sql query
alter table user add primary key (id)
and than try it will work
There are two possible reasons :
The id column is not the primary key, and probably you table doesn't have a primary key at all.
Create a primary key like this :
alter table user add primary key (id)
If you insert an value of 0 in an auto increment column, a new id is generated. An auto incremented column must not contain the value 0.
There is also a more general problem with your approach : in fact you only insert the user id and the rank, other compulsory fields in the table (username) are missing. The insert part does not seem to be valid for this reason. If you use an insert on duplicate key update, you must make sure that the result is correct which ever of insert and update is executed.
I have a table with columns id, user_id, post_id, like, views. When a user click the Like button, a row will be added to the table with the corresponding user_id and post_id, and like will be set to 1. If the row already exist and the like column already is 1, nothing will happen.
When the user visits a particular page, a row will be added to the table with the corresponding user_id and post_id, and view will be set to 1. However if the row already exist, the value in view will be incremented.
Problem: I tried using INSERT INTO mytable ... ON DUPLICATE KEY UPDATE like = 1, but the primary key of the table is id and not user_id or post_id. If I set the primary key to either user_id or post_id, there will be a problem because the row will only be duplicated if there exist a row with the same user_id and post_id.
In this situation, how should the query be built?
Or will a better situation be to split the table into 2 tables, one for likes and 1 for views. If this is the case, I still need to make the row unique based on both user_id and post_id columns.
Or do multiple SQL queries?
Please advise, thanks!
I would suggest that you have a table for likes, and then in whatever table that you keep posts in, you add a row for views. So whenever this post is viewed, you simply update the view value for that post to view = view + 1.
Now to address the problem that you outlined about the primary keys, you should note that you can use a unique key in that scenario, which can apply to multiple columns and would fix the issue that you ran into. So for example if in your scenario you had a unique key that encompassed both the userid and postid, your database would not allow for two different rows in that table with the same userid and postid.
So for future reference, use a unique key if you need to :)
discard the id as primary key
use two tables
make primary key on (user_id, post_id)
when handle insert like, do a insert ignore
when handle insert view, do a insert .. duplicate key update view = view+1
I have 3 tables, images, icons, and banners, each with a unique primary key that is also auto_incremented named image_id, icon_id, and banner_id, respectively.
I'm looping through the above tables and I'm wondering if there's a way I can select the id column without specifying it's specific name.
Something like
SELECT PRIMARY_KEY
FROM {$table}
Where I don't have to change my table structure or use * as there would be much data to return and would slow down my application.
Just name the id columns id in each table. Reserve the whatever_id naming for foreign keys.
I'm not a LAMP guy, but it looks to me like you want the INFORMATION_SCHEMA tables.
A query something like :
SELECT pk.table_name, column_name as 'primary_key'
FROM information_schema.table_constraints pk
INNER JOIN information_schema.key_column_usage C
on c.table_name = pk.table_name and
c.constraint_name = pk.constraint_name
where constraint_type = 'primary key'
-- and pk.table_name LIKE '%whatever%'
This above query (filtered to whatever relevant set of tables you need) will give you bit a list of table names and associated Primary Keys. What that information on hand you could query something like :
SELECT {$PK_ColumnName}
FROM {$table}
Note, you might needs a more complicated syntax and string builder if you have composite primary keys (i.e. more than one field per key). Also, the information schema can be relatively expensive to query, so you'll either want to cache the result set up, or query it infrequently.
The PRIMARY key is different than the column that has the primary key on it. The primary key is both an index and a constraint that is placed on one or more columns, not a column itself. Your pseudocode query:
SELECT PRIMARY_KEY
FROM tablename
is equivalent to this:
SELECT keyname
FROM tablename
Which is invalid. What you really need to select is a column, not a key.
Unfortunately, there is no column alias or simple function that you can use to specify the columns that have the primary key constraint. It's most likely not available because the primary key can apply to more than one column.
To see which columns have the PRIMARY key constraint, you could use some reflection by querying the schema tables, using SHOW COLUMNS, etc.. Simply doing SELECT * FROM tablename LIMIT 1 would get you all the column names in the result, if you wanted to assume the first column had the primary key constraint.
Of course, you could just do SELECT * anyway, when you don't know the column name.
If you don't want to make an extra query to fetch the column name to construct the query, using built-in meta data, or your own, I'd heed Marc B's answer if you can.
Or you can use the standard SQL command
show columns from tablename
It will show the PRI column
Check the online documentation for more info
How do I double or triple the rows (duplication also fine) in an existing table using mysql?
This should do the trick, if you have no PRIMARY KEY or UNIQUE indexes.
INSERT INTO table SELECT * FROM table;
If you do have such indexes, simply list all the columns in the table that do not have these indexes. E.g. if colA has a UNIQUE or PRIMARY KEY index:
INSERT INTO table (colB, colC) SELECT colB, colC FROM table;
Note that this will only work if your ID column (colA) has the AUTO_INCREMENT property set (this is usually the case for integer ID columns). If not then you are out of luck. In that case you cannot use INSERT INTO ... SELECT to duplicate rows because you need to supply the unique indexes manually.
In words,
use select to get everything, than use insert....
You shouldn't do that.
Keep your tables in Normal form that means no duplicates.
INSERT INTO table (SELECT * FROM table)
You have to exclude the primary key.
INSERT INTO table (col1, col2) SELECT col1, col2 FROM table;
Do not select primary key.
You have to mention all the fields excluding primary key. I believe you have an auto-increment column do not mention that column in above command but include all other columns.
I agree with Col. Shrapnel: you should not do this.
Sander got it right:
if you want to do this, INSERT INTO
table SELECT * FROM table is the way
to go
If there is a PRIMARY AUTOINCREMENT key, insert into table (all-but-key) select all-but-key from table
If there are other UNIQUE keys, you can't do this.
Another dirty workaround:
SELECT * FROM TABLE UNION ALL SELECT * FROM TABLE
You could put this in a VIEW or a merge table...
An easy way to duplicate all rows in the same table:
INSERT INTO yourtable()
SELECT * FROM yourtable;
This ofc only works if you don't have any unique keys on the table.