Easiest Way Of Copying a Row in MySQL - mysql

what's the easiest way of to clone a row with a different ID in MySQL.
For example:
Products
product_id name price
------------------------
1 a 10
2 b 15
It looks like weird, but I need to clone product with id = 1. So the table will look like:
Products
product_id name price
------------------------
1 a 10
2 b 15
3 a 10

You can use subqueries:
INSERT INTO
donation (name,price)
SELECT name,price
FROM donation
WHERE product_id = 1

INSERT INTO Products (name, price) VALUES ((SELECT name FROM Products WHERE product_id = 1), (SELECT price FROM Products WHERE product_id = 2));

INSERT INTO Products (name, price)
VALUES
((SELECT name, price
FROM Products
WHERE product_id = 1));

If you want to clone a row with a single SQL statement and can't or don't want to list all the values but there is a primary key you can use:
INSERT INTO Products
SELECT *
FROM Products
WHERE product_id = 1
UNION ALL
SELECT *
FROM Products
WHERE product_id = 1
ON DUPLICATE KEY UPDATE product_id=(SELECT MAX(product_id)+1 FROM Products);
This tries to insert two copies of the row into the databse and when the first row insert fails due to a duplicate product_id it uses ON DUPLICATE KEY to update the existing row in the table to the next available product_id, which leaves the original product_id available for when the second row is inserted.

Related

mysql find records against multiple row condition

So here I have multiple table and joined them but here I have put simple example like:
here i am able to find all those items who has category_id 1 and 3 any one using in query, but now i need and condition here like where category 1 and 3 both matches.
here i need all those items who has category_id 1 and 3 both.
So how to do that?
mysql in query is matching anyone exist, so is there any other function which matches multiple values?
Using INNER JOIN with a subquery to get the items that have both category_id 1 and 3. The subquery would select all the item_id's that have category_id 1 or 3 and the main query would join with the subquery on the item_id.
SELECT p1.item_id, p1.product_id, p1.category_id
FROM PRODUCT p1
INNER JOIN (
SELECT item_id
FROM PRODUCT
WHERE category_id IN (1, 3)
GROUP BY item_id
HAVING COUNT(DISTINCT category_id) = 2
) p2 ON p1.item_id = p2.item_id
WHERE p1.category_id IN (1, 3);
Sample:
-- create
CREATE TABLE PRODUCT (
id INTEGER PRIMARY KEY,
item_id INTEGER NOT NULL,
product_id INTEGER NOT NULL,
category_id INTEGER NOT NULL
);
-- insert
INSERT INTO PRODUCT VALUES (3862, 297,0, 1);
INSERT INTO PRODUCT VALUES (3861, 297,0, 3);
INSERT INTO PRODUCT VALUES (3860, 23, 0,1);
Output:
item_id product_id category_id
297 0 3
297 0 1

Resolve union of 2 tables that have duplicate primary key by picking only 1 of the rows and skip the rest of the rows

I have 2 tables and i am joining them using the below Query
Select distinct EmailAddress,CUSTOMER_ID,Send_Date,Unique_key,sub_category
from table1
UNION ALL
Select distinct EmailAddress,CUSTOMER_ID,Send_Date,Unique_key,sub_category
from table2
I am using Unique_key as the primary key. It is the concatination of send date + customer id. Sometimes both the tables can have duplicate keys and hence I want to take only 1row in such cases using the above query
Table 1
EmailAddress CUSTOMER_ID Send_Date Unique_key sub_category
a#gmail.com 1001 07-08-2021 70820211001 chair
Table 2
EmailAddress CUSTOMER_ID Send_Date Unique_key sub_category
a#gmail.com 1001 07-08-2021 7082021100 book
What is expected results ?
EmailAddress CUSTOMER_ID Send_Date Unique_key sub_category
a#gmail.com 1001 07-08-2021 70820211001 chair
Only 1 record should appear in the final table & multiple rows should be skipped. I don't want to change anything in unique key format. Is there any workaround for this?
You need something like:
Select distinct EmailAddress,CUSTOMER_ID,Send_Date,sub_category
from table_1
UNION
SELECT EmailAddress,CUSTOMER_ID,Send_Date,sub_category FROM table_2
WHERE NOT EXISTS ( SELECT NULL
FROM table_1
WHERE table_1.EmailAddress = table_2.EmailAddress ) ;
The below select will return empty set, because you have the WHERE NOT EXISTS condition, return the non matching row.
SELECT EmailAddress,CUSTOMER_ID,Send_Date,sub_category
FROM table_2
WHERE NOT EXISTS ( SELECT NULL
FROM table_1
WHERE table_1.EmailAddress = table_2.EmailAddress
) ;
Demo: https://www.db-fiddle.com/f/pB6b5xrgPKCivFWcpQHsyE/24
Try with your data and let me know.

Update duplicate columns their foreign key - mysql

I have a table with products: a foreign key(fk id), name and more data. There are duplicates in name, but there are for example customers related to the fk id
Therefore I want to update the duplicates with the first matching fk id
Example:
fk id name
1 abc
2 abc
3 abc
67 abc
Table after update:
fk id name
1 abc
1 abc
1 abc
1 abc
So far I got a query to put them together in a comma separated list, but I am missing the Update:
SELECT
count(*) as amount,
group_concat(name) as names,
group_concat(id) as ids
FROM db.product
GROUP BY name
HAVING amount> 1;
In mysql you can use joins in update statements. I would create a subquery that returns the lowest id (min()) for each name that appears multiple times. Since in mysql you cannot select from the same table that is being updated, therefore an extra layer of subselect is added on the top of the subselect:
UPDATE db.product
INNER JOIN (SELECT * FROM
(SELECT name, min(id) as minid
FROM db.product
GROUP BY name
HAVING count(*)> 1) t2 ) t on t.name=db.product.name
SET db.product.id=t.minid;

MySQL, Gracefully Abort if subquery is Null?

I wrote a query that is throwing an error when it can't find a record:
Error
Column 'product_id' cannot be null
MySQL
INSERT INTO orders (date, product_id, quantity)
VALUES ('11/29/2012', (
SELECT product_id FROM products WHERE product_name = 'Oranges'
), 12)
;
I'm actually iterating in my PHP and some of the product_name records are not going to exist.
Can I say somehow that if the subquery returns nothing, gracefully stop/abort so the PHP can keep iterating?
Try this:
INSERT INTO orders (date, product_id, quantity)
SELECT '11/29/2012', product_id, 12
FROM products
WHERE product_name = 'Oranges'
If there is no matching product, the query will succeed but return no rows modified. If you wish you can read the number of rows modified from PHP when you execute the query.
Notice that if there are multiple products with product_name = 'Oranges' you'll get multiple rows inserted into your table.
If you want a record to be inserted anyway, you can try to fallback to e.g. 0 if no such product exists:
INSERT INTO orders (date, product_id, quantity)
VALUES ('11/29/2012', COALESCE((
SELECT product_id FROM products WHERE product_name = 'Oranges'
), 0), 12);

Insert select ON DUPLICATE KEY question

I asked this question yesterday:
Insert select with a twist question
Now i have the problem that i want the data to update itself if it is a duplicate row.
So i found that i could do it by doing this:
insert into product_quantity
(groupId, productId, quantity)
select 3, productId, quantity
from product_quantity
ON DUPLICATE KEY UPDATE
product_quantity.quantity = VALUES(product_quantity.quantity);
But i want the quantity to update itself by adding the quantity to the already existsing quantity.
So i want something like this:
ON DUPLICATE KEY UPDATE
product_quantity.quantity =
VALUES(product_quantity.quantity) + product_quantity.quantity;
So if i got:
id----groupId----productId----quantity
1 ----- 2 ------------2--------------5
2 ----- 3 ------------2--------------5
Where groupId and productId are unique.
And i do the Insert-select-duplicate query:
insert into product_quantity
(groupId, productId, quantity)
select 3, 2, 5
from product_quantity
ON DUPLICATE KEY UPDATE
product_quantity.quantity = VALUES(product_quantity.quantity) + *OLD QUANTITY*;
MySql should add the quantity on row 1 to row 2, so it would look like this:
id----groupId----productId----quantity
1 ----- 2 ------------2--------------5
2 ----- 3 ------------2--------------10
Anyone got an idea if this is possible?
INSERT
INTO product_quantity (groupId, productId, quantity)
VALUES (3, productId, quantity)
FROM product_quantity
ON DUPLICATE KEY
UPDATE quantity = 5 + VALUES(quantity);
I think this'll do what you need.