从 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
也许现实世界的情况比这个示例数据看起来更复杂。
在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
也许现实世界的情况比这个示例数据看起来更复杂。