簡體   English   中英

根據表B中的某些字段從表A中選擇

[英]Select from table A depending on some field in table B

我有

TableA (TableAId int PK, Name varchar) 
TableB (OtherId, TableAId FK, TimeBegin timestamp ,TimeEnd timestamp)

我想從TableA Name中選擇,TableB中的TimeEnd = NULL。

試過這樣的事情:

SELECT     TableAId, Name
FROM       TableA
WHERE      
(
TableAId NOT IN 
                (
                 SELECT TableAId FROM TableB WHERE TimeEnd is null
                )
);

它工作正常,當我有一些記錄具有null TimeEnd和一些非null TimeEnd,但它沒有工作,當我沒有沒有設置TimeEnd的記錄。

怎么解決?

嘗試這個

Select * from TableA a
Left Join TableB b ON a.TableAId = b.TableAId 
WHERE b.TimeEnd IS NULL

對於非空

Select * from TableA a
Left Join TableB b ON a.TableAId = b.TableAId 
WHERE b.TimeEnd IS NOT NULL

根據您的問題,有兩種可能的答案:

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為IS NULL。

第二個選擇返回TableA中的記錄,其中TableB fullfil TimeEnd中的所有匹配記錄為空。

第二個選擇可以重寫為

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值的記錄,則需要在所有上述select語句中將IS NULL切換為IS NOT NULL,反之亦然。

我想你可能需要先加入2個表,如下例所示:

SELECT     TableA.TableAId, TableA.Name
FROM       TableA
INNER JOIN TableB
ON TableA.TableAId = TableB.TableAId
WHERE      
(
TableA.TableAId NOT IN 
                (
                 SELECT TableAId FROM TableB WHERE TimeEnd is null
                )
);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM