簡體   English   中英

(My)SQL:如果子查詢不是空集,則返回子查詢

[英](My)SQL: If subquery is not an empty set, return subquery

這個問題專門針對MySQL,但我試圖以適用標准SQL的方式詢問它。

上下文:我正在嘗試通過以下方式確定結束日期:如果在輸入的開始日期之后存在另一個開始日期,請使用現有的開始日期作為結束日期; 否則,結束日期應為輸入的開始日期之后的30天。

我嘗試過的解決方案類似於以下內容:

SELECT
  IF(
    EXISTS(  
      SELECT
        DISTINCT start_date
      FROM table
      WHERE ? < start_date AND
            identifier = ?
      ORDER BY start_date
      LIMIT 1
    ), (
    SELECT
      DISTINCT start_date
    FROM table
    WHERE ? < start_date AND
          identifier = ?
    ORDER BY start_date
    LIMIT 1),
    DATE_ADD(?, INTERVAL 30 DAY)
  ) AS end_date

我的解決方案可行,但我希望有一個更優雅,更重復的解決方案。

通用解決方案將是一種解決方案-如果存在子查詢,則返回子查詢中的值; 否則,可以返回其他內容。

代替子查詢,進行左聯接(到表本身)

SELECT
COALESCE(t2.start_date, t1.start_date)
FROM table t1
LEFT JOIN table t2 ON t1.identifier = t2.identifier AND t1.start_date > t2.start_date

左連接的條目是存在還是不存在,這意味着它不是null或null。 COALESCE()函數返回其第一個參數,不為null。

針對您自己的回答,我建議使用:

SELECT
  COALESCE((
    SELECT MIN(start_date)
    FROM TABLE
    WHERE start_date > ? 
    AND   identifier = ?), (
    SELECT
      DATE_ADD(?, INTERVAL 30 DAY)
    )) AS end_date 

似乎更容易理解恕我直言。 即使外觀不同,它在后台所做的事情幾乎相同。

根據fancyPant的解決方案,我使用了COALESCE ,但使用的方式完全不同(因此,為什么我不能將響應完全標記為已接受)。

SELECT
  COALESCE((
    SELECT
      DISTINCT start_date
    FROM TABLE
    WHERE ? < start_date AND
          identifier = ?
    ORDER BY start_Date
    LIMIT 1), (
    SELECT
      DATE_ADD(?, INTERVAL 30 DAY)
    )) AS end_date

上面的查詢將完全按預期執行。 您的子查詢是COALESCE語句的第一個參數,第二個查詢是替代查詢。

暫無
暫無

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

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