2011-08-12 85 views
0

我正在寫一個複雜的MySQL查詢,我無法弄清楚如何完成它。當子查詢沒有返回任何行時刪除WHERE條件

這裏是一個的給我麻煩的部分(這只是我的查詢的一部分):

SELECT * FROM table AS t1 
WHERE date < (
    SELECT date FROM table AS t2 
    WHERE phase="B" AND t2.target = t1.target 
) 

基本上,我有一個項目,每一個與日期,相位(A,B,C)和目標。對於一個目標,有A型的多個項目,然後一個可選 B型的項目,然後與類型C.

對於每個目標物品,我想選擇所有以下這些條件的行:

  1. 如果以階段「B」的項目(可以叫他itemX),我想回到所有項目進行遜色於itemX
  2. 的日期的日期如果沒有項目與階段「B」,我想返回n all rows

date參數非常重要。在大多數情況下,這三個階段是不同的,並且不能重疊,但在某些情況下會發生這種情況。

這裏的問題是,我的子查詢不中的情況下2

的情況下,1返回任何行,和單個細胞如果我們在1的情況下,整個條件WHERE date < (...)是無關緊要的,不應該在查詢中應用。

我試過IFNULLEXISTS的幾種可能性,但我認爲我做錯了,因爲我不斷收到語法錯誤。

回答

1
SELECT m.* 
FROM (
     SELECT target, MAX(date) AS maxdate 
     FROM mytable 
     ) md 
JOIN mytable m 
ON  m.target = md.target 
     AND m.date < 
     COALESCE 
     (
     (
     SELECT date 
     FROM mytable mb 
     WHERE mb.target = md.target 
       AND mb.phase = 'B' 
     ORDER BY 
       mb.target, pmb.phase, mb.date 
     LIMIT 1 
     ), 
     maxdate + INTERVAL 1 SECOND 
     ) 

創建兩個指標:

mytable (target, date) 
mytable (target, phase, date) 

這種工作速度快。

+0

謝謝你工作=) – 3rgo

1

你可以嘗試

SELECT * FROM table AS t1 
left join 
table as t2 
on t1.Target = t2.Target 
and t2.phase="B" 
where t2.target is null OR 
OR t1.date < t2.Date 
+0

我不明白't2.target是null'部分。你能解釋一下嗎? – 3rgo

+0

通過執行左連接,您將包含連接左側的所有行,並僅匹配連接右側的行。假設左側表t1和右側表t2,在不滿足連接條件的情況下,t2中的任何列的值將爲空。由於這種情況下的目標是在我們的連接條件不滿足的情況下省略where子句(目標匹配並且t2階段值爲'B'),我們首先檢查連接條件是否失敗,如果是,我們返回一行。 – cmsjr

+0

如果連接條件成功,如果t1日期值小於t2日期值,則返回一行。由於t2.Target是我們連接條件的一部分,所以在沒有匹配的情況下它只會爲空。 – cmsjr

1

也許

SELECT * 
FROM table AS t1 
LEFT JOIN table AS t2 ON t2.target = t1.target AND (t1.date < t2.date) 
WHERE (phase = 'B') 

我假設table在查詢實際上是兩個表,你不這樣做自加入?如果是這樣,那麼你必須指定你指的是哪個表phase

0

您發佈的代碼被稱爲「每個條件反模式一個子查詢」。使用CASE-WHEN-THEN。

0
SELECT t1.* 
    FROM table t1 
    LEFT 
    JOIN (SELECT t.target 
       , MIN(t.date) AS b_date 
      FROM table t 
      WHERE t.phase = 'B' 
      GROUP BY t.target 
     ) t2 
    ON t1.target = t2.target AND t1.date < t2.b_date 

如果有一些保證一個給定的目標將不超過一排用「相」 =「B」最多,你可以通過不MIN和GROUP BY,這樣的:

SELECT t1.* 
    FROM table t1 
    LEFT 
    JOIN (SELECT t.target 
       , t.date AS b_date 
      FROM table t 
      WHERE t.phase = 'B' 
     ) t2 
    ON t1.target = t2.target AND t1.date < t2.b_date 
相關問題