使用 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