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

Check if all ID's in a Column have a specific value in another column, different tables

我有两个 table:

Table 1:

Id 
1232
1344
1313
4242
3242
555

Table 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

我想检查 table 1 中的所有 id 是否在所有月份(示例中为 1,2)的 sym 中都具有值 9,但仅针对那些对他们来说代码在 table 2 是'32'。

如果不是 return 我用逗号分隔 id 和缺少 9 的月份。 If Id in table 1 doesn't not at all in table 2 return null in the month column and the id.

示例中的输出应该是:

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)

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

谢谢!

您的请求中有很多条件不能很好地相互补充,因此查询可能看起来有点混乱,而且执行速度可能很慢。您需要一种方法将结果合并到逗号分隔列表中。 SQL 服务器没有内置的字符串连接聚合函数,所以你需要做一些事情 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 月份。如果您希望看到它们在 table 中的显示顺序,只需删除此行即可。

编辑: 删除了最初的 "thinking out loud" 答案并仅留下实际解决方案以防止混淆。

试试这个:

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
  • 我在这里创建一个 cte 来找出缺少的月份。

  • 必须创建派生的 table months 以包含所有月份。

  • 然后执行左连接,所以要么 table 2 中不存在一个项目来匹配,要么这个项目是错误的

  • 一旦我全部错了 link 使用 XML PATH

    创建字符串
    • Concatenate many rows into a single text string?

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 |