SQL N 到无关系 Table
SQL N To No Releationship Table
我有 3 个 table 这个名字
供应商:商店供应商信息
SupplierID
Name
1
Supplier 1
2
Supplier 2
3
Supplier 3
4
Supplier 4
产品:商店产品信息
ProductID
Name
1
Product 1
2
Product 2
3
Product 3
4
Product 4
5
Product 5
SupplierProduct : 对于供应商可以供应的商店产品
ProductID
SupplierID
2
1
3
1
4
1
2
2
3
2
4
2
3
3
4
3
1
4
2
4
4
4
我想编写一个查询来获取一堆产品 ID 和 return 具有所有这些产品 ID 的供应商 ID(N:N 关系)例如获取产品 ID 2,3 和 return 只是供应商 ID 1,2
您可以按如下方式使用intersect
:
select distinct SupplierID
from SupplierProduct
where ProductID = 2
intersect
select SupplierID
from SupplierProduct
where ProductID = 3
这是一道 Relational Division With Remainder 的题,有多个除数。
首先,为了能够很好地解决这个问题,您需要以表格形式输入数据。您可以为此使用 table 变量或 Table 值参数。
有很多解决方案。这是一个常见的:
- 将输入数据加入
SupplierProduct
table。在您的情况下,您只需要 Supplier
数据,因此在子查询中执行此操作。
- 将其分组并检查计数是否与输入的总计数相匹配
DECLARE @ProductInput TABLE (ProductID int);
INSERT @ProductInput (ProductID) VALUES (2),(3);
SELECT *
FROM Supplier s
WHERE (SELECT COUNT(*)
FROM SupplierProduct sp
JOIN @ProductInput pi ON pi.ProductID = sp.ProductID
WHERE sp.SupplierID = s.SupplierID
) = (SELECT COUNT(*) FROM @ProductInput)
;
另一个常见的解决方案是双 NOT EXISTS
。这验证了 没有 输入 没有 匹配。它通常被认为效率较低。
DECLARE @ProductInput TABLE (ProductID int);
INSERT @ProductInput (ProductID) VALUES (2),(3);
SELECT *
FROM Supplier s
WHERE NOT EXISTS (SELECT 1
FROM @ProductInput pi
WHERE NOT EXISTS (SELECT 1
FROM SupplierProduct sp
WHERE pi.ProductID = sp.ProductID
AND sp.SupplierID = s.SupplierID
)
);
试试这个:
DECLARE @Supplier TABLE (SupplierID int, Name varchar(50));
INSERT INTO @Supplier VALUES
(1, 'Supplier 1')
, (2, 'Supplier 2')
, (3, 'Supplier 3')
, (4, 'Supplier 4')
;
DECLARE @Product TABLE (ProductID int, Name varchar(50));
INSERT INTO @Product VALUES
(1, 'Product 1')
, (2, 'Product 2')
, (3, 'Product 3')
, (4, 'Product 4')
, (5, 'Product 5')
;
DECLARE @SupplierProduct TABLE (ProductID int, SupplierID int);
INSERT INTO @SupplierProduct VALUES
(2, 1)
, (3, 1)
, (4, 1)
, (2, 2)
, (3, 2)
, (4, 2)
, (3, 3)
, (4, 3)
, (1, 4)
, (2, 4)
, (4, 4)
;
DECLARE @ProductSelection TABLE (ProductID int)
INSERT INTO @ProductSelection
SELECT
ProductID
FROM @Product
WHERE 1=1
-- AND ProductID IN (2, 3) -- returns Suppliers 1, 2
-- AND ProductID IN (3, 4) -- returns Suppliers 1, 2, 3
AND ProductID IN (2, 4) -- returns Suppliers 1, 2, 4
;
WITH SupplierList AS
(
SELECT
RowNo = ROW_NUMBER() OVER (PARTITION BY SP.SupplierID ORDER BY SP.SupplierID)
, S.SupplierID
FROM @SupplierProduct SP
JOIN @ProductSelection P ON P.ProductID = SP.ProductID
JOIN @Supplier S ON S.SupplierID = SP.SupplierID
)
SELECT
SupplierID
FROM SupplierList
WHERE RowNo = (SELECT SUM(1) FROM @ProductSelection)
我有 3 个 table 这个名字
供应商:商店供应商信息
SupplierID | Name |
---|---|
1 | Supplier 1 |
2 | Supplier 2 |
3 | Supplier 3 |
4 | Supplier 4 |
产品:商店产品信息
ProductID | Name |
---|---|
1 | Product 1 |
2 | Product 2 |
3 | Product 3 |
4 | Product 4 |
5 | Product 5 |
SupplierProduct : 对于供应商可以供应的商店产品
ProductID | SupplierID |
---|---|
2 | 1 |
3 | 1 |
4 | 1 |
2 | 2 |
3 | 2 |
4 | 2 |
3 | 3 |
4 | 3 |
1 | 4 |
2 | 4 |
4 | 4 |
我想编写一个查询来获取一堆产品 ID 和 return 具有所有这些产品 ID 的供应商 ID(N:N 关系)例如获取产品 ID 2,3 和 return 只是供应商 ID 1,2
您可以按如下方式使用intersect
:
select distinct SupplierID
from SupplierProduct
where ProductID = 2
intersect
select SupplierID
from SupplierProduct
where ProductID = 3
这是一道 Relational Division With Remainder 的题,有多个除数。
首先,为了能够很好地解决这个问题,您需要以表格形式输入数据。您可以为此使用 table 变量或 Table 值参数。
有很多解决方案。这是一个常见的:
- 将输入数据加入
SupplierProduct
table。在您的情况下,您只需要Supplier
数据,因此在子查询中执行此操作。 - 将其分组并检查计数是否与输入的总计数相匹配
DECLARE @ProductInput TABLE (ProductID int);
INSERT @ProductInput (ProductID) VALUES (2),(3);
SELECT *
FROM Supplier s
WHERE (SELECT COUNT(*)
FROM SupplierProduct sp
JOIN @ProductInput pi ON pi.ProductID = sp.ProductID
WHERE sp.SupplierID = s.SupplierID
) = (SELECT COUNT(*) FROM @ProductInput)
;
另一个常见的解决方案是双 NOT EXISTS
。这验证了 没有 输入 没有 匹配。它通常被认为效率较低。
DECLARE @ProductInput TABLE (ProductID int);
INSERT @ProductInput (ProductID) VALUES (2),(3);
SELECT *
FROM Supplier s
WHERE NOT EXISTS (SELECT 1
FROM @ProductInput pi
WHERE NOT EXISTS (SELECT 1
FROM SupplierProduct sp
WHERE pi.ProductID = sp.ProductID
AND sp.SupplierID = s.SupplierID
)
);
试试这个:
DECLARE @Supplier TABLE (SupplierID int, Name varchar(50));
INSERT INTO @Supplier VALUES
(1, 'Supplier 1')
, (2, 'Supplier 2')
, (3, 'Supplier 3')
, (4, 'Supplier 4')
;
DECLARE @Product TABLE (ProductID int, Name varchar(50));
INSERT INTO @Product VALUES
(1, 'Product 1')
, (2, 'Product 2')
, (3, 'Product 3')
, (4, 'Product 4')
, (5, 'Product 5')
;
DECLARE @SupplierProduct TABLE (ProductID int, SupplierID int);
INSERT INTO @SupplierProduct VALUES
(2, 1)
, (3, 1)
, (4, 1)
, (2, 2)
, (3, 2)
, (4, 2)
, (3, 3)
, (4, 3)
, (1, 4)
, (2, 4)
, (4, 4)
;
DECLARE @ProductSelection TABLE (ProductID int)
INSERT INTO @ProductSelection
SELECT
ProductID
FROM @Product
WHERE 1=1
-- AND ProductID IN (2, 3) -- returns Suppliers 1, 2
-- AND ProductID IN (3, 4) -- returns Suppliers 1, 2, 3
AND ProductID IN (2, 4) -- returns Suppliers 1, 2, 4
;
WITH SupplierList AS
(
SELECT
RowNo = ROW_NUMBER() OVER (PARTITION BY SP.SupplierID ORDER BY SP.SupplierID)
, S.SupplierID
FROM @SupplierProduct SP
JOIN @ProductSelection P ON P.ProductID = SP.ProductID
JOIN @Supplier S ON S.SupplierID = SP.SupplierID
)
SELECT
SupplierID
FROM SupplierList
WHERE RowNo = (SELECT SUM(1) FROM @ProductSelection)