我有一个很难解释的问题。我有两个桌子
表1 :(这类似于装运表)
ID ShippingId ProductId1 ProductId2
1 100 A A1
2 100 A A2
3 100 A A3
4 100 A A4
5 100 A A5
6 200 B B1
7 200 B B2
8 300 B A1
9 300 B A2
表2 :(这与ProductId1和ProductId2之间的关系有关)
ID ProductId1 ProductId2
1 A A1
2 A A2
3 A A3
4 A A4
5 A A5
6 B B1
7 B B2
如果装运“ 100”包括所有“ A”项目,则应为“ true” 发货“ 200”和“ 300”不包括其主要产品的所有部分。所以预期的输出应该像
ShippingId ProductId1 IsIncludeAll
100 A true
200 B false
300 A true
你们能帮我吗?
DECLARE @table1 AS TABLE
(
ShippingID INT,
ProductId1 INT,
ProductId2 INT
)
DECLARE @table2 AS TABLE
(
ProductId1 INT,
ProductId2 INT
)
INSERT INTO @table1 (ShippingId,ProductId1,ProductId2) VALUES (100,111, 1119)
INSERT INTO @table1 (ShippingId,ProductId1,ProductId2) VALUES (100,111, 1118)
INSERT INTO @table1 (ShippingId,ProductId1,ProductId2) VALUES (100,111, 1117)
INSERT INTO @table1 (ShippingId,ProductId1,ProductId2) VALUES (100,111, 1116)
INSERT INTO @table1 (ShippingId,ProductId1,ProductId2) VALUES (100,111, 1115)
INSERT INTO @table1 (ShippingId,ProductId1,ProductId2) VALUES (200,222, 2229)
INSERT INTO @table1 (ShippingId,ProductId1,ProductId2) VALUES (200,222, 2228)
INSERT INTO @table1 (ShippingId,ProductId1,ProductId2) VALUES (300,111, 1117)
INSERT INTO @table1 (ShippingId,ProductId1,ProductId2) VALUES (300,111, 1116)
INSERT INTO @table2 (ProductId1,ProductId2) VALUES ( 111, 1119)
INSERT INTO @table2 (ProductId1,ProductId2) VALUES ( 111, 1118)
INSERT INTO @table2 (ProductId1,ProductId2) VALUES ( 111, 1117)
INSERT INTO @table2 (ProductId1,ProductId2) VALUES ( 111, 1116)
INSERT INTO @table2 (ProductId1,ProductId2) VALUES ( 111, 1115)
INSERT INTO @table2 (ProductId1,ProductId2) VALUES ( 222, 2229)
INSERT INTO @table2 (ProductId1,ProductId2) VALUES ( 222, 2228)
ShippingId ProductId1 IsIncludeAll
100 A true
200 B false
300 A false
答案 0 :(得分:3)
总的猜测是,样本DDL和DML与样本数据不匹配,但这也许是这样吗?
SELECT S.ShippingID,
T2.ProductId1,
CASE COUNT(CASE WHEN T1.ProductId2 IS NULL THEN 1 END) WHEN 0 THEN 'true' ELSE 'false' END AS IsIncludeAll
FROM @table2 T2
CROSS APPLY (SELECT DISTINCT
sq.ShippingID,
sq.ProductId1
FROM @table1 sq
WHERE sq.ProductId1 = T2.ProductId1) S
LEFT JOIN @table1 T1 ON T2.ProductId1 = T2.ProductId1
AND T1.ProductId2 = T2.ProductId2
AND S.ShippingID = T1.ShippingID
GROUP BY S.ShippingID,
T2.ProductId1;
答案 1 :(得分:1)
对样本数据和输出有点困惑。根据我的想法,请检查此查询并输出。
------Step 1. concatenate product1 and product2 with ShippingID wise,product1 wise order by ShippingID,ProductId1,ProductId2-------------------
declare @Shipping as table
(
ShippingID INT,
ProductId1 INT,
ProductDesc varchar(max)
)
insert @Shipping
SELECT Shipping.ShippingID,Shipping.ProductId1,
LEFT(Shipping.prod_desc,Len(Shipping.prod_desc)-1) As prod_desc
FROM
(
SELECT DISTINCT T2.ShippingID, T2.ProductId1,
(
SELECT cast(T1.ProductId1 as varchar(10))+'-' +cast(T1.ProductId2 as varchar(10))+ '|' AS [text()]
FROM dbo.table1 T1
WHERE T1.ShippingID = T2.ShippingID and T1.ProductId1=T2.ProductId1
ORDER BY T1.ShippingID,ProductId1,ProductId2
FOR XML PATH ('')
) prod_desc
FROM dbo.table1 T2
) Shipping
------Step 2. concatenate product1 and product2 with product1 wise order by ProductId1,ProductId2-------------------
declare @relation as table
(
ProductId1 INT,
ProductDesc varchar(max)
)
insert @relation
SELECT relation.ProductId1,LEFT(relation.prod_desc,Len(relation.prod_desc)-1) As prod_desc
FROM
(
SELECT DISTINCT T2.ProductId1,
(
SELECT cast(T1.ProductId1 as varchar(10))+'-' +cast(T1.ProductId2 as varchar(10))+ '|' AS [text()]
FROM dbo.table2 T1
WHERE T1.ProductId1=T2.ProductId1
ORDER BY ProductId1,ProductId2
FOR XML PATH ('')
) prod_desc
FROM dbo.table2 T2
) relation
------Step 1. use left join to match with concatinated string of every product1. if matches return True otherwise False-------------------
select a.ShippingID,a.ProductId1,case when b.ProductDesc is null then 'False' else 'True' end as IsIncludeAll
from @Shipping a
left join @relation b
on a.ProductId1=b.ProductId1 and a.ProductDesc=b.ProductDesc
-----Result-----------
------------+---------------+--------------
ShippingID | ProductId1 | IsIncludeAll
------------+---------------+--------------
100 | 111 | True
200 | 222 | True
300 | 111 | False