我有两张桌子:
表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)
但是我真的不知道如何使查询运行整个月并插入结果,就像我在输出中提到的那样。有帮助吗?
谢谢!
答案 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
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 |