选择与多对多关系的一侧无关的值

and*_*dyb 2 sql-server except

我有一个类别和值之间的连接表,指示哪些类别与每个值相关联。我想找到与每个类别无关的值。

类别:

ID CategoryName
-- ------------
 1 category1
 2 category2
 3 category3
Run Code Online (Sandbox Code Playgroud)

类别值:

CategoryID ValueID
---------- -------
         1       1
         1       2
         2       1
         3       2
Run Code Online (Sandbox Code Playgroud)

价值:

ID ValueName
-- ---------
 1 value1
 2 value2
 3 value3
Run Code Online (Sandbox Code Playgroud)

我想要的查询输出如下:

CategoryID ValueID ValueName
---------- ------- ---------
         1       3 value3
         2       2 value2
         2       3 value3
         3       1 value1
         3       3 value3
Run Code Online (Sandbox Code Playgroud)

我很困惑如何将其作为查询来处理。“连接”表似乎阻止了通常的 LEFT JOIN WHERE null 方法。所以任何建议将不胜感激。

ype*_*eᵀᴹ 5

你需要的所有组合CategoryValue(一个CROSS JOIN除了那些出现在)CategoryValue。这可以通过LEFT JOIN / IS NULL

SELECT 
    c.CategoryID, v.ValueID, v.ValueName
FROM 
    Category AS c
  CROSS JOIN
    Value AS v
  LEFT JOIN
    CategoryValue AS cv
      ON  cv.CategoryID = c.CategoryID
      AND cv.ValueID = v.ValueID
WHERE
   cv.CategoryID IS NULL ;
Run Code Online (Sandbox Code Playgroud)

NOT EXISTS

SELECT 
    c.CategoryID, v.ValueID, v.ValueName
FROM 
    Category AS c
  CROSS JOIN
    Value AS v
WHERE
   NOT EXISTS
     ( SELECT *
       FROM CategoryValue AS cv
       WHERE cv.CategoryID = c.CategoryID
         AND cv.ValueID = v.ValueID 
     ) ;
Run Code Online (Sandbox Code Playgroud)

EXCEPT解决方案:

SELECT 
    c.CategoryID, v.ValueID, v.ValueName
FROM 
    Category AS c
  CROSS JOIN
    Value AS v

EXCEPT

SELECT 
    cv.CategoryID, v.ValueID, v.ValueName
FROM 
    CategoryValue AS cv
  JOIN
    Value AS v
      ON  cv.ValueID = v.ValueID ;
Run Code Online (Sandbox Code Playgroud)