2009-08-18 75 views
1

早上好。我遇到查詢問題。我想在查詢中選擇某些內容,但前提是其他字段是有意義的。下面的查詢將更好地解釋如果語句在sql查詢中

select 
Case isnull(rl.reason,'Not Found') 
    When 'D' then 'Discontinued' 
    When 'N' then 'Not Found' 
    When 'I' then 'Inactive' 
    When 'C' then 'No Cost' 
    When '' then 'Not Found' 
End as Reason, ***If statement to select pv.descriptor only if reason is in ('D','I','C')***pv.descriptor 
from table1 as rl 
left join table2 as v on v.field= rl.field 


***Here i want an if statment to run if reason is in ('D','I','C')*** 
left join table3 as pv on 
Case rl.scantype 
when 'S' then cast(ltrim(rtrim(pv.field#1)) as varchar) 
when 'U' then cast(ltrim(rtrim(pv.field#2)) as varchar) 
when 'V' then cast(ltrim(rtrim(pv.vfield#3)) as varchar) 
end 
= rl.scan and pv.vend_no = rl.vendnum 
***'**If statement ends***** 

left join storemain..prmastp as p on p.emuserid = rl.userid 
where rl.scandate between GetDate() -7 and GetDate() order by rl.scandate desc 

我想if語句只選擇如果選擇的理由是「d」,「我」,or'C」的描述符。如果不是,我想要一個空值,因爲除非原因是'D','I','C',否則我不會做這個變量。順便說一下,我可以使用case語句,其中我在左連接的中間使用它。它工作得很好。這不是我的問題。

+0

查詢並沒有真正更好地解釋它。 – 2009-08-18 14:43:42

+0

您無法在SQL中使用CASE進行流程控制。 – PhilPursglove 2009-08-18 14:49:40

+0

所以我們已經確定了什麼不是問題。什麼是問題? – Eric 2009-08-18 14:55:13

回答

1

認爲你只想加盟pv如果v.reason(D, I, C) - 是這樣嗎?如果這是你的問題,只是改變你的JOIN子句:

LEFT JOIN table3 as pv ON 
    LTRIM(RTRIM(
     CASE rl.scantype 
      WHEN 'S' THEN pv.field#1 
      WHEN 'U' THEN pv.field#2 
      WHEN 'V' THEN pv.field#3 
     END 
    )) = rl.scan 
    AND rl.vendnum = pv.vend_no 
    AND rl.reason IN ('D', 'I', 'C') 

當然,你也有「如果語句來選擇pv.descriptor只有當原因是(‘d’,‘我’,‘C’ )[as] pv.descriptor「在SELECT子句中。因此,假設你想相反,試試這個:

SELECT 
    /* your other columns */ 
    CASE 
     WHEN rl.reason IN ('D', 'I', 'C') THEN pv.descriptor 
     ELSE NULL --optional, since it'll default to NULL 
    END as descriptor 
+0

我認爲這是我的答案。 +1,同時。 – Eric 2009-08-18 15:24:56

0

是什麼激發了兩個查詢的組合?連接可能會導致需要完全不同的評估計劃......基於變量值(或更糟 - 列!)在兩個計劃之間進行選擇並不是查詢優化程序的優點。

如果您編寫兩個查詢並使用SQL IF語句將流控制轉換爲其中一個查詢,那麼您會好得多。

編輯:如果有兩行來自rl,那麼查詢會返回什麼,一個理由= D,一個理由= S?

+0

我編輯了查詢。我把錯誤的字段名稱。一個原因永遠不會是's',而是簡單的類型。雖然好的觀察。 – Eric 2009-08-18 15:07:31

0

我會保持簡單,以便將來支持您的代碼的人可以弄清楚如何維護它(例如,當他們添加另一個原因代碼時)。

它可能不如性能,但它更易於維護。

此外,有沒有一種方法可以在表中獲得這些代碼並測試標記,而不是讓它們在sql中硬編碼?

+0

我這樣做的原因是爲了加快查詢速度。我不希望在表3中搜索'未找到'的掃描號碼,因爲表3有數百萬條記錄,並且它將通過它們搜索沒有,因爲找不到掃描號碼(因此數據名稱)。我不能在代碼中這樣做,因爲我試圖避免構建,現在是一個很長的過程,以便將代碼發送到我們的其他位置。 – Eric 2009-08-18 15:14:10

+0

如果您試圖在連接之前排除這些記錄,則可以在不採用非標準方法的情況下執行此操作。我知道不使用查找表是更高性能的,但折衷是維護,這些代碼是由商業而非IT決定的。 – Beth 2009-08-18 15:18:03

+0

另請考慮優化您的維護方法,然後再進行性能優化。以儘可能簡單易懂的方式滿足商業需求,然後優化代碼的性能。 – Beth 2009-08-18 15:24:00

2

如果你想在一個查詢中,你必須進行連接。如果您使用左連接和case語句,則可以確保pv.descriptor在空白處顯示,如果在某些情況下這是您想要的。

如果你想控制流量,你就需要使用T-SQL

如果性能是你的關心,你不應該在計算的值來加盟。重新考慮數據庫設計。您想要爲連接創建新列,並且如果您有多對多關係,可能需要創建中間表。

+0

我相信你是對的。 +1 – Eric 2009-08-18 15:24:21