根据您的问题,有两种可能的答案:
IF OBJECT_ID('dbo.TableB') IS NOT NULL
DROP TABLE dbo.TableB;
IF OBJECT_ID('dbo.TableA') IS NOT NULL
DROP TABLE dbo.TableA;
CREATE TABLE dbo.TableA
(
TableAId INT PRIMARY KEY,
Name VARCHAR(100)
);
CREATE TABLE dbo.TableB
(
OtherId INT PRIMARY KEY,
TableAId INT FOREIGN KEY REFERENCES TableA ( TableAId ),
TimeBegin DATETIME,
TimeEnd DATETIME
);
INSERT INTO dbo.TableA
( TableAId, Name )
VALUES ( 1, 'aaa' ),
( 2, 'bbb' ),
( 3, 'ccc' ),
( 4, 'ddd' );
INSERT INTO dbo.TableB
( OtherId, TableAId, TimeBegin, TimeEnd )
VALUES ( 1, 1, GETDATE(), NULL ),
( 2, 2, GETDATE(), GETDATE() ),
( 3, 2, GETDATE(), NULL ),
( 4, 3, GETDATE(), GETDATE() );
SELECT A.*
FROM dbo.TableA A
WHERE EXISTS ( SELECT 1
FROM dbo.TableB B
WHERE A.TableAId = B.TableAId
AND B.TimeEnd IS NULL );
SELECT A.*
FROM dbo.TableA A
WHERE EXISTS ( SELECT 1
FROM dbo.TableB B
WHERE A.TableAId = B.TableAId
AND B.TimeEnd IS NULL )
AND NOT EXISTS ( SELECT 1
FROM dbo.TableB B
WHERE A.TableAId = B.TableAId
AND B.TimeEnd IS NOT NULL );
第一个选择返回 TableA 中的所有记录,其中在 TableB 中存在至少一个匹配记录且 TimeEnd 为 NULL。
第二个选择返回 TableA 中所有匹配记录在 TableB fullfil TimeEnd 中为 NULL 的记录。
第二个选择可以重写为
SELECT A.*
FROM dbo.TableA A
LEFT JOIN ( SELECT TableAId,
MIN(CASE WHEN TimeEnd IS NULL THEN 1
ELSE 0
END) AllAreNull
FROM dbo.TableB
GROUP BY TableAId
) AS B
ON A.TableAId = B.TableAId
WHERE B.AllAreNull = 1;
这有点不太容易理解,但在大多数情况下应该执行得更快。但是您应该运行自己的性能测试以确保。
如果 TableA 中的每条记录在 TableB 中最多有一条记录,则可以使用第一个 select 语句。
最后,您的代码与描述文本不匹配。如果您实际上正在寻找具有 endtime 值的记录,则需要在上述所有选择语句中将 IS NULL 与 IS NOT NULL 切换出来,反之亦然。