I have a table that aggregate items and their categories. An item can have multiple categories. Here is the simplified schema and example data:
Table name: xref, (itemID, catID) defined as primary key
itemID | catID
-------+-------
4059 | 159
4059 | 219
I also have a category merge function. When doing this, I also move products that linked in source category to the destination (merged) category . For moving items from category 159 to 219, I use a SQL like this:
UPDATE `xref` SET `catID` = 219 WHERE `catID` = 159
But the update fails because there is already a 4059-219 (PK constraint).
The desired result is
itemID | catID
-------+-------
4059 | 219
I can't use stored procedures or functions on the database but can implement the required steps in my application.
SELECT * FROM xref WHERE catID IN (159, 219) GROUP BY itemID HAVING COUNT(*) >= 2
is a correct approach? I can't use @JNevill's approach because I don't know to-be-affected itemID's beforehand. But that give me an idea for this 2 step solution.
UPDATE IGNORE `xref` SET `catID` = 219 WHERE `catID` = 159
DELETE FROM `xref` WHERE `catID` = 159
Thanks for the all other answers/comments.
Try following query:
UPDATE `xref`
SET `catID` = 219
WHERE `catID` = 159
and `itemID` not in (select 'itemID'
from (select *from 'xref') x
where 'catID' = 219)
;
Hope it helps!
This way temporarily removes your constraints to allow the update and then puts them back at the end.
If your database is a production database TEST ON A COPY!
# set up tables for the purpose of this example
CREATE TABLE Item
(
ItemId INT,
ItemName VARCHAR(255),
PRIMARY KEY (ItemId)
);
CREATE Table Category
(
CatId INT,
CatName VARCHAR(255),
PRIMARY KEY (CatId)
);
CREATE TABLE xref
(
ItemId INT,
CatId INT,
PRIMARY KEY (ItemId,CatId),
FOREIGN KEY (ItemID) REFERENCES Item(ItemId),
FOREIGN KEY (CatId) REFERENCES Category(CatId)
);
# insert data for the purpose of this example
INSERT INTO Item
VALUES
(1,'Hammer'),
(2,'Chisel'),
(3,'Wrench');
INSERT INTO Category
VALUES
(159,'Tool'),
(219,'Toy'),
(3,'foo');
INSERT INTO xref
VALUES
(1,159),
(1,219),
(2,159),
(3,3);
START TRANSACTION;
# remove constraints so we can run the update
ALTER TABLE xref DROP FOREIGN KEY xref_ibfk_1;
ALTER TABLE xref DROP FOREIGN KEY xref_ibfk_2;
ALTER TABLE xref DROP PRIMARY KEY;
# Update the categories
UPDATE xref SET CatId = 219 WHERE CatId = 159;
# Copy the table into a tmep table but exclude duplicates we have created above
CREATE TEMPORARY TABLE IF NOT EXISTS xref_tmp AS (SELECT DISTINCT
ItemId,
CatId
FROM xref);
# Empty the original table
DELETE FROM xref;
# Copy the clean results back to the orginal table
INSERT INTO xref
SELECT * FROM xref_tmp;
# put our constaints back
ALTER TABLE xref ADD PRIMARY KEY (ItemId,CatId);
ALTER TABLE xref ADD FOREIGN KEY (ItemID) REFERENCES Item(ItemID);
ALTER TABLE xref ADD FOREIGN KEY (CatID) REFERENCES Category(CatID);
COMMIT
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.