SQL左联接-获取值如果两个值在TableB中都不为null或TableB中缺少行

时间:2018-09-04 20:52:40

标签: sql sql-server

http://sqlfiddle.com/#!18/d1cf0/6

TABLE HEADER 
(
     [HeaderID] VARCHAR(3), 
     [description] VARCHAR(50),
      [ProcessStatus] bit 
);

TABLE DETAILS
(
    [HeaderID] VARCHAR(3), 
    [DETAIL_VALUE_1] VARCHAR(50),
    [DETAIL_VALUE_2] VARCHAR(50)
);

SELECT DISTINCT 
    H.HEADERID 
FROM 
    HEADER H 
LEFT JOIN
    DETAILS D ON H.HeaderID = D.HeaderID 
              AND (D.DETAIL_VALUE_1 IS NOT NULL AND 
                   D.DETAIL_VALUE_2 IS NOT NULL)
WHERE H.ProcessStatus = 0

基于SQL Fiddle中提供的示例数据,以上查询返回1,2,3..

我需要查询仅返回2,3,因为标题1具有DETAIL_VALUE_1不为空但DETAIL_VALUE_2为空的记录之一。

这些表可能有上百万条记录。 标题表是锚点。即,标题表将具有标志“ ProcessStatus”以指示已处理了哪些记录。

谢谢。

3 个答案:

答案 0 :(得分:2)

在我看来,您想要查找不存在“不良条件”的行……也许是双重负数?

select 
  H.HEADERID 
from
  HEADER H 
where 
  not exists 
  ( 
    select * 
    from 
      Details D 
    where
      H.HeaderID= D.HeaderID 
      and 
      (
        D.DETAIL_VALUE_1 IS NULL 
        or
        D.DETAIL_VALUE_2 IS NULL
      )
    )

答案 1 :(得分:1)

您可以使用NOT IN

SELECT H.HEADERID 
FROM HEADER H 
WHERE HeaderID not in (select d.HeaderID from DETAILS d where (DETAIL_VALUE_1 is null or DETAIL_VALUE_2 is null))

请注意,我没有JOIN到桌子上,并且我也没有DISTINCT

http://sqlfiddle.com/#!18/d1cf0/15/0

如果您打算使用DETAILS中的列,您仍然可以加入其中。

SELECT DISTINCT H.HEADERID 
FROM HEADER H 
LEFT JOIN DETAILS D on
D.HeaderID = H.HeaderID
WHERE H.HeaderID not in (select d.HeaderID from DETAILS d where (DETAIL_VALUE_1 is null or DETAIL_VALUE_2 is null))

答案 2 :(得分:1)

您可以利用COUNT仅对非空值进行计数,并检查HeaderIDDETAILS值的计数与{ {1}}和DETAIL_VALUE_1值。由于所有DETAIL_VALUE_2的值均为0,因此该查询也可以在DETAILS中没有行的地方使用。

COUNT

输出:

SELECT H.HeaderID
FROM HEADER H 
LEFT JOIN DETAILS D ON H.HeaderID= D.HeaderID
GROUP BY H.HeaderID
HAVING COUNT(D.HeaderId) = COUNT(D.DETAIL_VALUE_1) AND COUNT(D.HeaderID) = COUNT(D.DETAIL_VALUE_2)

SQLFiddle