2014-10-03 89 views
0
SELECT Services.Type, Description 
    , CASE 
     WHEN id = $user_id THEN 'YES' 
     ELSE 'NO' 
    END AS Checked 
    , Details 
from Services 
LEFT JOIN SellerServices ON SellerServices.Type = Services.Type  
WHERE `id` =$user_id 
OR 
Services.Type NOT IN 
    (
    SELECT SellerServices.Type 
    FROM  SellerServices 
    where id =$user_id 
) 

要解釋涉及的表格,SellerServices是一個描述特定賣家提供哪些服務的表格。有人可以改善此查詢嗎?

服務描述了所有的服務。

如果我不加入這些表,一個簡單的「select * from Services where 1」幾乎可以完成要返回的行的目標,但是因爲它只是找到了能夠完成任務的子查詢:

第二個子句中,Services.Type不在子查詢中查找$ user_id不匹配的每個服務,或者它爲空。這些是賣家不提供的服務。

第一個子句找到他提供的服務。 case語句以我喜歡的格式輸出結果。

它的工作原理,但有沒有辦法改進它?

+1

我會看看這個網站... http://codereview.stackexchange.com/ – 2014-10-03 14:50:12

+0

我看着這個......我還沒有很多咖啡。實際返回的查詢是什麼?你想要一個所有服務的列表,如果該'$ user_id'與這些服務相關聯,則是Y/N? – 2014-10-03 14:58:51

+0

您需要指定您正在使用的數據庫後端。性能調整非常依賴於數據庫。在SQL服務器中,我建議使用Union All(或UNion,如果數據集不相互排斥)而不是OR,並且不存在而不存在。 – HLGEM 2014-10-03 15:01:34

回答

2

如果你想用「是」或「否」指示其是否提供沿着列表中的服務,你可以做這樣的事情:

select s.type, s.description, 
     (case when exists (select 1 from SellerServices ss where ss.Type = s.Type and ss.id = $user_id) 
      then 'YES' 
      else 'NO' 
     end) as Checked, 
     s.details 
from services s; 

您的問題不指定details來從,所以我從services猜測。

你也可以寫爲left outer join,假設有在SellerServices表中沒有重複:

select s.type, s.description, 
     (case when ss.Type is not null 
      then 'YES' 
      else 'NO' 
     end) as Checked, 
     ss.details 
from Services s left join 
    SellerServices ss 
    on ss.Type = s.Type and ss.id = $user_id; 

這可以處理details或者從表來。

+0

後一種解決方案有效,並且它比我所具有的更復雜。謝謝。 (假設沒有重複項,只要$ user_id被修復就不會有重複項)如果不是,可能會有很多重複項。 – 3pi14 2014-10-03 18:46:58