2015-12-01 31 views
2

我有兩個表:檢查所有ID的列中的具有在另一列中的特定值時,不同的表

表1:

Id 
1232 
1344 
1313 
4242 
3242 
555 

表2:

Id sym mnth code 
1232 9  1  32 
1344 15  1  14 
1313 10  1  32 
4242 11  1  32 
3242 9  1  32 
1232 9  2  32 
1344 13  2  14 
1313 9  2  32 
4242 10  2  32 
3242 9  2  32 

我想要檢查表1中的所有id是否在所有月份的sym中都有值9(示例中爲1,2),但僅針對表2中的代碼爲'32'的那些id。

如果沒有將我的身份證號碼和缺少9的月份以逗號分隔。如果表1中的Id在表2中完全不存在,則在月份列和id中返回null。

例子中的輸出應該是:

ID month 
1313 1 
4242 1,2 
555 NULL 

1344 doesn't exist because the code column for hime is not 32. 

我開始寫這篇:

SELECT table1.id 
FROM table1 
WHERE not EXISTS (SELECT id FROM table2 
        WHERE table2.sml = '9' AND table2.code = 32) 

但我真的不知道如何使查詢運行的所有月份和堵塞結果就像我在輸出中提到的那樣。任何幫助?

謝謝!

+2

添加table1.id = table2.id的子查詢的WHERE子句? – jarlh

+0

對不起,不明白。 – Jordan1200

+1

想象一下你可能需要一個'OUTER APPLY',並且對於你之後的'month'的輸出,你還需要一個自定義的聚合函數。 –

回答

1
  • 這裏我創建了一個CTE找出該月份失蹤。

  • 必須創建衍生表months以包含所有月份。

  • 然後執行左連接,所以無論是didnt存在於表2中的一個項目,以匹配或項目是錯誤的

  • 一旦我把所有的錯鏈接創建使用XML PATH

Sql Fiddle Demo

WITH cte as (
    SELECT t1.*, t2.sym, t2.mnth, t2.code 
    FROM Table1 t1 
    CROSS JOIN (select 1 month_id union select 2) months  
    LEFT JOIN Table2 t2 
     ON t2.[id] = t1.id 
    AND t2.[mnth] = months.month_id 
    WHERE ([code] = 32 OR [code] is NULL) 
     AND ([sym] <> 9 OR [sym] is NULL) 

), MAIN as (
    SELECT DISTINCT c2.Id, (SELECT c1.mnth + ',' as [text()] 
          FROM cte c1 
          WHERE c1.Id = c2.Id 
          ORDER BY c1.Id 
          For XML PATH ('') 
       ) [months] 
    FROM cte c2 
) 
SELECT Id, 
     IIF(len([months]) > 0, 
      LEFT ([months], len([months])-1), 
      NULL) as [months] 
FROM Main 

輸出

| Id | months | 
|------|--------| 
| 555 | (null) | 
| 1313 |  1 | 
| 4242 | 1,2 | 
+0

請問爲什麼你不接受答案?而且你沒有留下任何讚揚或評論 –

+0

嘿,代碼沒有爲我工作,但我嘗試了其他解決方案,因爲我沒時間繼續這個想法來顯示。謝謝你所有的答案。你非常有幫助。 – Jordan1200

+0

對不起,如果沒有工作,但我想我解決你在這裏提出的問題。也許以後你可以試着用附加信息提出一個新問題。 –

2

您的請求中有很多條件不會互相恭維,所以查詢可能會顯得有些雜亂,並且可能執行緩慢。您需要一種將結果合併到逗號分隔列表中的方法。 SQL Server沒有內置字符串連接集合函數,因此您需要在similar to this other question上工作才能獲得month輸出。

我想出的,讓你的結果,你追求的是:

SELECT t1.id, t2.[month] 
FROM Table1 t1 
OUTER APPLY (
    SELECT stuff((SELECT ', ' + convert(varchar, mnth) 
       FROM Table2 
       WHERE id = t1.id and sym <> 9 and code = 32 
       ORDER BY mnth ASC 
       for xml path('') 
       ),1,2,'') as [month] 
) t2 
WHERE 
    id in (SELECT id FROM Table2 WHERE sym <> 9 and code = 32) 
or id not in (SELECT id FROM Table2); 

注意,我添加了ORDER BY mnth ASC線,這樣的結果month場在非9個符號邏輯順序。如果您希望看到它們出現在表格中的順序,只需刪除此行。

編輯:刪除了最初的「大聲思考」的答案,並留下了實際的解決方案,以防止混淆。

+0

謝謝邁克。任何方式將其發佈到兩個月以上? 當我添加'3,4,5,..'它給我一個錯誤。 – Jordan1200

+0

@ Jordan1200我其實並不熟悉'stuff'函數,因爲在其他問題中看到它是我第一次遇到它。我可以嘗試更多地調整查詢。 Juan提供的接受答案在所有情況下都會給你正確的輸出嗎?如果是這樣,我可能會刪除我的答案,因爲它最終會誤導,如果它不處理超過2個。 –

+0

@ Jordan1200恰恰相反......當我添加3,4,5個月並運行時,我發現我的解決方案仍在繼續去工作,但接受的答案只顯示「1,2」。在這兩種情況下,我都沒有看到任何錯誤。你在看什麼?請注意,我在我的答案中找到了一些內容,如果它們不在表格中順序排列,那麼它不會顯示月份,因此我正在更新我的答案以包含已排序的結果。 –

1

試試這個:

select * from 
    (select 
     id, 
     stuff((select ', ' + convert(varchar, month_) 
       from tbl2 t2 
       where t1.id = t2.id 
       and t2.sym != 9 and t2.code != 32 
       for xml path('')),1,2,'') month_ 
    from tbl1 t1 
    group by id 

UNION 

select t1.id, convert(varchar, t2.month_) 
       from tbl1 t1 
       JOIN tbl2 t2 on t1.id = t2.id 
       and t2.sym = 9 and t2.code = 32) as t 

where t.month_ is not null 
相關問題