我试图比较两个"列表"在同一个表格中获取customerId
存在的记录,但storeid
不存在customerid
。
列表(表格定义)
name listid storeid customerid
BaseList 1 10 100
BaseList 1 11 100
BaseList 1 11 102
NewList 2 11 100
NewList 2 12 102
NewList 2 12 103
查询:
SELECT
NewList.*
FROM
Lists NewList
LEFT JOIN
Lists BaseList ON BaseList.customerid = NewList.customerid
WHERE
BaseList.listid = 1
AND NewList.listid = 2
AND NewList.storeid <> BaseList.storeid
AND NOT EXISTS (SELECT 1
FROM Lists c
WHERE BaseList.customerid = c.customerid
AND BaseList.storeid = c.storeid
AND c.listid = 2)
目前的结果:
NewList 2 11 100
NewList 2 12 102
但我希望只得到结果
NewList 2 12 102
存在具有storeid 11的customerid 100。
答案 0 :(得分:2)
如果表定义包含列Name
(如您所说),则下面的语句将返回您的结果。
我不明白你的选择陈述。
SELECT *
from @table
WHERE NAME = 'NewList'
AND customerID IN (SELECT CustomerID FROM @table WHERE NAME = 'BaseList')
AND storeID NOT IN (SELECT storeID FROM @table WHERE NAME = 'BaseList')
答案 1 :(得分:1)
此动态数据透视图将显示所有列表值以及存在相同组合的位置:
我再添加一个组:
insert into Lists(name, listid, storeid, customerid) values('AnotherNew',3,11,100);
insert into Lists(name, listid, storeid, customerid) values('AnotherNew',3,11,102);
insert into Lists(name, listid, storeid, customerid) values('AnotherNew',3,10,100);
以下是声明:
编辑:这个新陈述 - 我认为 - 更好,因为它涉及到customerid和storeid的不同组合
DECLARE @listNames VARCHAR(MAX)=
STUFF(
(
SELECT DISTINCT ',[' + name + ']'
FROM Lists
FOR XML PATH('')
),1,1,'');
DECLARE @SqlCmd VARCHAR(MAX)=
'
WITH DistinctCombinations AS
(
SELECT DISTINCT customerid,storeid
FROM Lists AS l
)
SELECT p.*
FROM
(
SELECT DistinctCombinations.*
,OtherExisting.name AS OtherName
,CASE WHEN l.listid IS NULL THEN '''' ELSE ''X'' END AS ExistingValue
FROM DistinctCombinations
LEFT JOIN Lists AS l ON DistinctCombinations.customerid=l.customerid AND DistinctCombinations.storeid=l.storeid
OUTER APPLY
(
SELECT x.name
FROM Lists AS x
WHERE x.customerid=l.customerid
AND x.storeid=l.storeid
) AS OtherExisting
) AS tbl
PIVOT
(
MIN(ExistingValue) FOR OtherName IN (' + @ListNames + ')
) AS p';
EXEC(@SqlCmd);
结果
customerid storeid AnotherNew BaseList NewList
100 10 X X NULL
100 11 X X X
102 11 X X NULL
102 12 NULL NULL X
103 12 NULL NULL X
这是之前的方法:
DECLARE @listNames VARCHAR(MAX)=
STUFF(
(
SELECT DISTINCT ',[' + name + ']'
FROM Lists
FOR XML PATH('')
),1,1,'');
DECLARE @SqlCmd VARCHAR(MAX)=
'
WITH DistinctLists AS
(
SELECT DISTINCT listid
FROM Lists AS l
)
SELECT p.*
FROM
(
SELECT l.*
,OtherExisting.name AS OtherName
,CASE WHEN l.listid IS NULL THEN '''' ELSE ''X'' END AS ExistingValue
FROM DistinctLists
INNER JOIN Lists AS l ON DistinctLists.listid= l.listid
CROSS APPLY
(
SELECT x.name
FROM Lists AS x
WHERE x.listid<>l.listid
AND x.customerid=l.customerid
AND x.storeid=l.storeid
) AS OtherExisting
) AS tbl
PIVOT
(
MIN(ExistingValue) FOR OtherName IN (' + @ListNames + ')
) AS p';
EXEC(@SqlCmd);
这就是结果:
name listid storeid customerid AnotherNew BaseList NewList
AnotherNew 3 10 100 NULL X NULL
AnotherNew 3 11 100 NULL X X
AnotherNew 3 11 102 NULL X NULL
BaseList 1 10 100 X NULL NULL
BaseList 1 11 100 X NULL X
BaseList 1 11 102 X NULL NULL
NewList 2 11 100 X X NULL
答案 2 :(得分:0)
在小提琴中测试过。请用更多数据进行测试。但是对于你的输入它似乎工作正常。
的 SQLFiddle Demo
强>
SELECT c.*
FROM (
SELECT n.*
FROM (
SELECT *
FROM lists
WHERE NAME = 'NewList'
) n
LEFT JOIN (
SELECT *
FROM lists
WHERE NAME = 'BaseList'
) b ON b.storeid = n.storeid
WHERE b.listid IS NULL
) c
WHERE c.customerid IN (
SELECT DISTINCT customerid
FROM lists
WHERE NAME = 'BaseList'
)