比较数据库中存在一列但另一列不存在的记录

时间:2016-01-29 06:59:36

标签: sql sql-server

我试图比较两个"列表"在同一个表格中获取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。

Fiddle

3 个答案:

答案 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'
        )