从WHERE子句不是常量的表中筛选



在表A中,clmn1是帐户,clmn2可以取3个值:txt1、txt2或txt3。对于每个帐户,clmn2中可以有多个值。我需要过滤账户,只取txt1或txt2,如果两者都有,txt1比txt2更可取。Txt3被排除在之外

TableA
clmn0 clmn1
1      txt1
1      txt2
1      txt3
2      txt2
2      txt3
3      txt1
3      txt3
4      txt3
5      txt2
6      txt1
6      txt2
…      ….

过滤表:

clmn0 clmn1
1      txt1
2      txt2
3      txt1
5      txt2
6      txt1
…      ….

我的尝试是:

SELECT * 
FROM TableA 
Where 
(clmn1='txt1' OR clmn1='txt2') AND clmn1='txt1'
OR
(clmn1<>'txt1' OR clmn1<>'txt2') AND clmn1='txt2'

但我有

clmn0 clmn1
1   txt1
1   txt2
2   txt2
3   txt1
5   txt2
6   txt1
6   txt2

我想出了一个不同的@T.Peter解决方案,不确定什么表现更好:

SELECT * FROM Table WHERE clmn1='txt1' UNION SELECT * FROM Table WHERE
(clmn0 NOT IN(SELECT clmn0 FROM Table WHERE clmn1='txt1') AND
clmn1='txt2')

谢谢@hansUp。我很抱歉,Steave在这个例子中是绝对正确的。然而,正如Steave所说,实际情况更为复杂。字符串txt1、tx2、txt3…只是示例,不能排序。不过,我可以添加一个clmn2,其中clmn1中的txt1匹配clmn2=1、txt2 clmn2=2、txt3 clmn3=3等等,并进行某种排序,因此MIN((函数有效。。。想知道GROP BY中的聚合应该如何?

我可能遗漏了一些东西,但使用简单的MIN不是更简单吗?

SELECT clm0, min(clm1) as clm1
FROM [table]
WHERE clm1 <> 'txt3'
GROUP BY clm0

也许现实世界的情况使它比这个样本数据看起来更复杂。

您可以使用row_number获取第一行:

select clmn0,clmn1 from (
select row_number()over(partition by clmn0 order by clmn1) rn, cte.* 
from [table]
where clmn1 <> 'txt3'
) a
where rn = 1

然而,这个查询是针对sql server的,OP没有提到也没有标记正在使用的dbmsSO在不同的dbms中,您需要更改row_number语法以对应语法
这里是db<gt;小提琴以便更好地检查。


重新编辑

我不确定这个查询在MS Access中是否有效,但这个查询没有使用row_number:

select clmn0,clmn1 from (
select a.*, 
(select top 1 clmn1 from [table] b where a.clmn0 = b.clmn0 order by clmn1) as First_clmn
from [table] a 
) c
where clmn1=First_clmn
and clmn1 <> 'txt3'

我认为top语法确实存在于MS Access中,所以请尝试一下
这里还有db<gt;不停摆弄

最新更新