sql - 具有依赖于多行的多个排列的查询
问题描述
(SQL2014 如果有影响的话)
说我有 [tableA]
id ResultID SampleID ERRORCODE col4 colN
1 9001 1100 0 ... ...
2 9002 1100 100 ... ...
3 9003 1100 200 ... ...
4 9004 1100 300 ... ...
5 9005 1101 0 ... ...
6 9006 1101 0 ... ...
7 9007 1101 0 ... ...
8 9008 1101 0 ... ...
9 9009 1102 0 ... ...
10 9010 1102 100 ... ...
11 9011 1102 200 ... ...
12 9012 1102 0 ... ...
我想生成一个只显示SampleID
包含所有错误代码 0、100、200 和 300 的样本集(由公共 val 标识)的结果。即上述内容将减少为:
id ResultID SampleID ERRORCODE col4 colN
1 9001 1100 0 ... ...
2 9002 1100 100 ... ...
3 9003 1100 200 ... ...
4 9004 1100 300 ... ...
因此,我需要一个查询,它一次查看多行并向下选择具有(i)列中某些键值的组,这里是[ERRORCODE]
,(ii)另一列中的值一致,这里是[SampleID]
。我看过:
却一点喜悦都没有。适用于 oliboon 的子查询对我来说只适用于一行。Olga 的代码根本不起作用,而 Aushin 的代码产生了意想不到的结果(删除一半的语法并没有改变它们)!
N00b 到 SQL,所以我有点失落!
列出的一些解决方案中使用的“table”关键字似乎对我不起作用 - 可能这些答案旨在创建一个子表,然后在子查询中对其解决方案进行进一步解析。如果我尝试以下操作,我得到的只是“关键字表附近的语法不正确”错误:
select distinct SampleID from table [my].[db].[path].[tableA]
我想到了格式的查询
SELECT *
From [tableA]
where
[SampleID] in (Select [SampleID] from [tableA] where [ERRORCODE] = 0) and
[SampleID] in (Select [SampleID] from [tableA] where [ERRORCODE] = 100)
本来可以,但是如果两个 [ERRORCODE] 检查是针对相同的代码,即 100,它只会返回一个结果。这当然是无用的。它逐行检查,而不是执行逻辑门的第一部分,然后是第二部分。
如果我能够完成 [ERRORCODE]=0 的第一部分,然后从 [ERRORCODE]=100 的那些 SampleID 中向下选择并重复,那么就可以了。不知道该怎么做。
编辑:Ach FFS。事实证明,我正在寻找的每一个错误代码都必须相互排斥——无论是什么组合,都不能同时出现两个错误代码。我假设在我拥有的数据库的大小中,某处会有一个组合。
我用错误代码检查了我的查询,我可以从一个不合格的 SELECT * 中看到它们并排放置并证明它有效。
我想问题是无效的。
解决方案
我有点失落。如果您想要包含所有四个错误代码的样本,那么这应该可以满足您的需求:
select a.*
from [tableA] a
where a.SampleID in (Select a2.SampleID from tableA a2 where a2.ERRORCODE = 0) and
a.SampleID in (Select a2.SampleID from tableA a2 where a2.ERRORCODE = 100) and
a.SampleID in (Select a2.SampleID from tableA a2 where a2.ERRORCODE = 200) and
a.SampleID in (Select a2.SampleID from tableA a2 where a2.ERRORCODE = 300) ;
这应该有效,尽管问题声称它没有。它不一定会有最好的性能。
我通常建议聚合以设置样本 ID:
select sampleid
from tablea
where errorcode in (0, 100, 200, 300)
group by sampleid
having count(distinct errorcode) = 4;
如果您不想重复并覆盖所有错误代码,请使用:
having count(distinct errorcode) = 4 and count(*) = 4
这也可能不是在所有情况下都具有最佳性能。但是性能是可以预测的——它几乎不会根据您要查找的代码数量而变化。该having
子句可以使这变得非常通用。
然后,如果您想要所有原始数据,您可以使用join
、in
或exists
:
select a.*
from tablea a join
(select sampleid
from tablea
where errorcode in (0, 100, 200, 300)
group by sampleid
having count(distinct errorcode) = 4
) a2
on a2.sampleid = a.sampleid;
推荐阅读
- c# - 如何使用 c# 获取 Azure Blob 存储容器中现有目录的列表?
- php - Codeigniter - Sweetalert 在控制器中不起作用
- openstreetmap - 更新交通信息 OSRM
- c++ - 如何使用 NtQueryInformationThread 查找堆栈的基地址?
- java - 我在一个包含数组列表的子类上有一个构造函数,并且对构造函数的调用在使用 Java 时给了我一个错误
- crystal-reports - 当子报表没有数据时抑制主报表中的记录
- spring-boot - 使用 Spring Zuul 和 Spring Initializer 进行正确的依赖管理
- json.net - Newtonsoft 不隐藏空值
- azure-cosmosdb-sqlapi - Sql string for this result?
- c - 使用位运算符返回 C 中最负的二进制补数