使用 SQL 更新多对多 table
Updating a many to many table with SQL
我有一个 table 和动物
CREATE TABLE Animals
(
AnimalId int NOT NULL,
Color int NOT NULL,
Breed int NOT NULL,
Genre int NOT NULL,
);
和一个table完全一样,但一切都是可选的(除了钥匙)
CREATE TABLE Expenses
(
ExpenseId int NOT NULL,
Color int,
Breed int,
Genre int,
);
最后是多对多 table:
CREATE TABLE AnimalsExpenses
(
ExpenseId int NOT NULL FOREIGN KEY REFERENCES Expenses(ExpenseId),
AnimalId int NOT NULL FOREIGN KEY REFERENCES Animals(AnimalId),
);
记录 (a, e) 应该在 table AnimalsExpenses if
((SELECT Color FROM Animals WHERE AnimalId = a) = (SELECT Color FROM Expenses WHERE ExpenseId = e)
OR (NULL) = (SELECT Color FROM Expenses WHERE ExpenseId = e))
AND
((SELECT Breed FROM Animals WHERE AnimalId = a) = (SELECT Breed FROM Expenses WHERE ExpenseId = e)
OR (NULL) = (SELECT Breed FROM Expenses WHERE ExpenseId = e))
AND
((SELECT Genre FROM Animals WHERE AnimalId = a) = (SELECT Genre FROM Expenses WHERE ExpenseId = e)
OR (NULL) = (SELECT Genre FROM Expenses WHERE ExpenseId = e))
...如何查询更新 AnimalsExpenses ?也就是说:它删除了不应该出现在 n-m table 上的记录,并添加了需要出现的记录
示例:
------ Animals -------------------
AnimalId Color Breed Genre
----------------------------------
1 1 1 1
2 1 1 2
3 1 2 2
----- Expenses -------------------
ExpenseId Color Breed Genre
----------------------------------
1 NULL NULL NULL (applies to every animal)
2 NULL 2 NULL (applies to animals of breed 2)
3 1 2 2 (applies exactly to animal 3)
----- AnimalsExpenses -------------------------------------------
AnimalId ExpenseId Is it ok?
-----------------------------------------------------------------
1 1 yes, because "expense 1" applies to all
2 1 yes, because "expense 1" applies to all
3 1 yes, because "expense 1" applies to all
1 2 no, breed doesnt match
2 2 no, breed doesnt match
3 2 yes, because "expense 2" matches breed with "animal 3"
1 3 no, breed and genre doesnt match
2 3 no, breed doesnt match
3 3 yes, everything matches
你为什么不直接 运行 分类 table 然后 运行
Insert into AnimalsExpenses
select a.AnimalId
, e.ExpenseId
from Animals a
inner join Expenses e on a.Breed = ISNULL(e.Breed, a.Breed)
AND a.Color = ISNULL(e.Color, a.Color)
AND a.Genre = ISNULL(e.Genre, a.Genre)
我建议您这样重写 WHERE
条件:
ISNULL(Expenses.Color, Animals.Color) = Animals.Color
AND ISNULL(Expenses.Breed, Animals.Breed) = Animals.Breed
AND ISNULL(Expenses.Genre, Animals.Genre) = Animals.Genre
也看看COALESCE
。
我有一个 table 和动物
CREATE TABLE Animals
(
AnimalId int NOT NULL,
Color int NOT NULL,
Breed int NOT NULL,
Genre int NOT NULL,
);
和一个table完全一样,但一切都是可选的(除了钥匙)
CREATE TABLE Expenses
(
ExpenseId int NOT NULL,
Color int,
Breed int,
Genre int,
);
最后是多对多 table:
CREATE TABLE AnimalsExpenses
(
ExpenseId int NOT NULL FOREIGN KEY REFERENCES Expenses(ExpenseId),
AnimalId int NOT NULL FOREIGN KEY REFERENCES Animals(AnimalId),
);
记录 (a, e) 应该在 table AnimalsExpenses if
((SELECT Color FROM Animals WHERE AnimalId = a) = (SELECT Color FROM Expenses WHERE ExpenseId = e)
OR (NULL) = (SELECT Color FROM Expenses WHERE ExpenseId = e))
AND
((SELECT Breed FROM Animals WHERE AnimalId = a) = (SELECT Breed FROM Expenses WHERE ExpenseId = e)
OR (NULL) = (SELECT Breed FROM Expenses WHERE ExpenseId = e))
AND
((SELECT Genre FROM Animals WHERE AnimalId = a) = (SELECT Genre FROM Expenses WHERE ExpenseId = e)
OR (NULL) = (SELECT Genre FROM Expenses WHERE ExpenseId = e))
...如何查询更新 AnimalsExpenses ?也就是说:它删除了不应该出现在 n-m table 上的记录,并添加了需要出现的记录
示例:
------ Animals -------------------
AnimalId Color Breed Genre
----------------------------------
1 1 1 1
2 1 1 2
3 1 2 2
----- Expenses -------------------
ExpenseId Color Breed Genre
----------------------------------
1 NULL NULL NULL (applies to every animal)
2 NULL 2 NULL (applies to animals of breed 2)
3 1 2 2 (applies exactly to animal 3)
----- AnimalsExpenses -------------------------------------------
AnimalId ExpenseId Is it ok?
-----------------------------------------------------------------
1 1 yes, because "expense 1" applies to all
2 1 yes, because "expense 1" applies to all
3 1 yes, because "expense 1" applies to all
1 2 no, breed doesnt match
2 2 no, breed doesnt match
3 2 yes, because "expense 2" matches breed with "animal 3"
1 3 no, breed and genre doesnt match
2 3 no, breed doesnt match
3 3 yes, everything matches
你为什么不直接 运行 分类 table 然后 运行
Insert into AnimalsExpenses
select a.AnimalId
, e.ExpenseId
from Animals a
inner join Expenses e on a.Breed = ISNULL(e.Breed, a.Breed)
AND a.Color = ISNULL(e.Color, a.Color)
AND a.Genre = ISNULL(e.Genre, a.Genre)
我建议您这样重写 WHERE
条件:
ISNULL(Expenses.Color, Animals.Color) = Animals.Color
AND ISNULL(Expenses.Breed, Animals.Breed) = Animals.Breed
AND ISNULL(Expenses.Genre, Animals.Genre) = Animals.Genre
也看看COALESCE
。