从 table 中过滤 WHERE 子句不是常量

filter from a table with WHERE clause not constant

在Table中,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
   …      ….

Table 过滤:

   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。抱歉,史蒂夫在这个例子中是完全正确的。然而,正如史蒂夫所说,实际情况要复杂得多。字符串 txt1、tx2、txt3... 仅作为示例,无法排序。不过,我可以添加一个 clmn2,在 clmn1 中的 txt1 匹配 clmn2=1、txt2 clmn2=2、txt3 clmn3=3 等具有某种排名,因此 MIN() 函数起作用...想知道聚合如何在GROP BY 应该是?

您可以使用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 没有提到也没有标记正在使用的 dbms。 SO 在不同的 dbms 中,您需要更改 row_number 语法以对应语法。
这里是 db<>fiddle 以便更好地检查。


重新编辑

我不确定这个查询在 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'

我认为 MS-Access 中确实存在 top 语法,所以请尝试一下。
这里还有 db<>fiddle.

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

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

也许现实世界的情况比这个示例数据看起来更复杂。