检查列中的所有ID是否在另一列(不同的表)中具有特定值

时间:2015-12-01 14:14:26

标签: sql sql-server select exists

我有两张桌子:

表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),但仅针对那些id为他们的代码在表2中是' 32'。

如果没有以逗号分隔我的身份和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)

但是我真的不知道如何使查询运行整个月并插入结果,就像我在输出中提到的那样。有帮助吗?

谢谢!

3 个答案:

答案 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-sym月份。如果您更愿意看到它们出现在表格中的顺序,只需删除此行即可。

修改:删除了最初的“大声思考”的答案,只留下了实际的解决方案以防止混淆。

答案 1 :(得分: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

答案 2 :(得分:1)

  • 在这里,我创建一个cte来找出缺少的月份。

  • 必须创建一个派生表months以包含所有月份。

  • 然后执行左连接,因此表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 |