[英]LEFT OUTER JOIN with IS NULL
我在LEFT OUTER JOIN鏈上僅能處理90%的情況。
days:
id, date_value
1, 2017-01-01
2, 2017-01-02
3, 2017-01-03
periods:
id, starts_on, ends_on, name, federal_state_id, country_id
1, 2017-01-01, 2017-01-01, Test1, 1, NULL
2, 2017-01-03, 2017-01-03, Test2, 2, NULL
slots:
id, days_id, periods_id
1, 1, 1
2, 3, 2
SELECT days.date_value, periods.name, periods.federal_state_id
FROM days
LEFT OUTER JOIN slots ON (days.id = slots.day_id)
LEFT OUTER JOIN periods ON (slots.period_id = periods.id)
WHERE days.date_value >= '2017-01-01' AND
days.date_value <='2017-01-03' AND
(periods.id IS NULL OR periods.country_id = 1 OR
periods.federal_state_id = 1)
ORDER BY days.date_value;
2017-01-01, Test1, 1
2017-01-02, NULL, NULL
但我想得到這個結果:
2017-01-01, Test1, 1
2017-01-02, NULL, NULL
2017-01-03, NULL, NULL
據我了解,由於最后一個條目的federal_state_id
periods.id IS NULL
不匹配,因為存在period #2
的federal_state_id
為2
。
如何更改SQL查詢以獲取所需的結果?
如果將期間條目上的條件移至加入條件,則它們將不屬於與槽加入的集合,從而為name
和federal_state_id
產生所需的NULL
。 因此,將要加入的集合將僅包含:
periods:
id, starts_on, ends_on, name, federal_state_id, country_id
1, 2017-01-01, 2017-01-01, Test1, 1, NULL
這樣,可以返回每個日期輸入(范圍內的條件除外)。 查詢將如下所示:
SELECT
days.date_value,
periods.name,
periods.federal_state_id
FROM days
LEFT OUTER JOIN slots
ON (days.id = slots.day_id)
LEFT OUTER JOIN periods
ON (slots.period_id = periods.id) AND
((periods.country_id = 1 OR
periods.federal_state_id = 1))
WHERE
days.date_value >= '2017-01-01' AND
days.date_value <='2017-01-03'
ORDER BY
days.date_value;
請注意,不再需要conditions.id periods.id IS NULL
條件,因為將條件套用到僅包含時隙和時間段的集合,其中每個時間段條目都是主鍵,因此每個id條目將具有一個id值。 並且,由於插槽和期間由左連接插槽連接,因此不會刪除期間表中不匹配的內容。
在您的原始查詢中,您首先加入了period的所有條目(如果id匹配),然后刪除了所有沒有所需country_id
或federal_state_id
。 這將刪除period
有匹配但不符合條件的日期。
我總是建議格式化SQL語句。 錯誤更容易發現。
將條件移動到聯接,例如:
SELECT days.date_value
,periods.name
,periods.federal_state_id
FROM dbo.days
LEFT OUTER JOIN dbo.slots
ON days.id = slots.days_id
LEFT OUTER JOIN dbo.periods
ON slots.periods_id = periods.id
AND (
periods.country_id = 1
OR periods.federal_state_id = 1
)
WHERE days.date_value >= '2017-01-01'
AND days.date_value <='2017-01-03'
ORDER BY days.date_value
;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.