簡體   English   中英

SQL JOIN-為每個表A返回一行,無論表B是否具有值

[英]SQL JOIN - return a row for each Table A, regardless if Table B has values or not

下面的查詢應為每個Reading_Type返回一行,外加該Reading_Type和日期的已保存Reading值,如果未保存任何Reading,則返回0。

SELECT
      t.*
    , ISNULL(r.Reading, 0) AS Reading
FROM
    Reading_Type t
LEFT JOIN
    Reading r ON t.Reading_Type_ID = r.Reading_Type_ID
WHERE
    r.Reading_Date = @date
    OR r.Reading_Date IS NULL
  • 如果在任何日期都沒有保存讀數,它確實可以工作
  • 如果僅保存了所選日期的讀數,則該方法確實起作用。
  • 如果Reading_Type已保存的閱讀日期X它工作,沒有保存的閱讀日期Y,和搜索是日期Y.

Reading_Type表:

Reading_Type_ID  Reading_Type
-----------------------------
1                Red
2                Blue
3                Green

Reading表(表為空):

Reading_ID  Reading_Type_ID  Reading  Reading_Date
-----------------------------------------------------

@date = April 15, 2016查詢返回:

Reading_Type_ID  Reading_Type  Reading
----------------------------------------
1                Red           0
2                Blue          0
3                Green         0

Reading表(表中包含4月15日的數據):

Reading_ID  Reading_Type_ID  Reading  Reading_Date
-----------------------------------------------------
1           1                5        April 15, 2016
2           3                8        April 15, 2016

@date = April 15, 2016查詢返回:

Reading_Type_ID  Reading_Type  Reading
----------------------------------------
1                Red           5
2                Blue          0
3                Green         8

使用@date = April 7, 2016查詢返回:

Reading_Type_ID  Reading_Type  Reading
----------------------------------------
1                Red           0
3                Green         0

第三個查詢仍應為Reading_Type = Blue返回一行,其中0為Reading。 如何解決我的查詢?

您的WHERE標准正在導致您的過濾器問題(僅自己完成了一百萬次左右)。 嘗試以下方法:

SELECT
      t.*
    , ISNULL(r.Reading, 0) AS Reading
FROM
    Reading_Type t
LEFT JOIN
    Reading r ON t.Reading_Type_ID = r.Reading_Type_ID
AND r.Reading_Date = @date

在這種情況下,請忽略WHERE子句(除非您想進一步過濾數據)。

以下是一些有助於詳細說明此SQL功能的信息: 在FROM或WHERE子句中指定聯接

如果r.Reading_Date可以為null,並且您想包含這些內容,則

SELECT t.*, ISNULL(r.Reading, 0) AS Reading
FROM Reading_Type t
LEFT JOIN Reading r 
       ON r.Reading_Type_ID = t.Reading_Type_ID
      AND isnull(r.Reading_Date, @date) = @date

該查詢正在執行您要的操作。 它正在執行左聯接(如果存在則將返回來自t所有記錄和來自r記錄)...然后它將應用您的where條件。 如果r.Reading_Date既不是NULL也不是@date ,則該查詢中的記錄將從結果集中排除。

我認為,如果我正確理解的話,您想要的是子選擇上的左聯接...所以更像這樣:

SELECT
  t.*, ISNULL(r.Reading, 0) AS Reading
FROM
Reading_Type t
LEFT JOIN (
    SELECT Reading_Type_ID, Reading 
    FROM Reading
    WHERE Reading_Date = @date
    OR Reading_Date IS NULL
) r
ON t.Reading_Type_ID = r.Reading_Type_ID

暫無
暫無

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

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