SQL IN-运算符:考虑多列
SQL IN-Operator: consider multiple columns
这是我的 table:
Column1 Column2
1 A
2 B
3 B
2 C
4 B
我有以下 SQL 查询来获取 column1 与数字输入列表匹配的所有行,例如“1, 2, 3”:
SELECT * FROM table WHERE column1 IN (1, 2, 3);
这个查询是由一个附加每个数字的程序生成的。
现在我希望 column1 的所有行都匹配一个数字,同时匹配 column2 的一个字符,例如“1和A,2和B,4和B”。
一个可能的查询是:
SELECT * FROM table
WHERE (column1 = 1 and column2 = 'A')
OR (column1 = 2 and column2 = 'B')
OR (column1 = 4 and column2 = 'B')
如果我的列表有几千个值对而我的 table 有几十万个条目怎么办?
有没有更好的方法来获得相同的结果,还是我必须附加一千个 "OR"s?
遗憾的是这不起作用:
SELECT * FROM table
WHERE (column1, column2) IN ((1, 'A'), (2, 'B'), (4, 'B'))
试试这个
WITH CTE1 AS(SELECT column1,column2,ROW_NUMBER() OVER (PARTITION BY column1
ORDER BY column2) AS Row_Count FROM Table_Name)
SELECT column1,column2 FROM CTE1 WHERE Row_Count = 1
这就是我会做的。它通常比使用 OR 的 IN 表现更好,并且在我看来更具可读性。
SELECT * FROM TABLE
INNER JOIN
(
SELECT 1 AS col1, 'a' AS col2 UNION
SELECT 2, 'b' UNION
SELECT 4, 'b'
) AS tbl
ON tbl.col1=TABLE.col1 AND tbl.col2=TABLE.col2
SELECT * FROM table
WHERE (column1, column2)
IN (
SELECT 1 c1, 'A' c2 FROM dual
UNION ALL
SELECT 2, 'B' FROM dual
UNION ALL
SELECT 4, 'B' FROM dual
)
创建具有匹配索引的 table 或 table 变量。加载用户的过滤器,并加入主 table.
试试下面一个
create table #temp (id int, val varchar(1))
insert into #temp (id,val) values (1,'A')
insert into #temp (id,val) values (2,'B')
insert into #temp (id,val) values (3,'B')
insert into #temp (id,val) values (4,'C')
insert into #temp (id,val) values (5,'C')
select * from #temp where val in (
select val from #temp where id in (1,2,3))
好吧,我需要类似的东西,但是对于一个 DELETE 语句,我想在其中删除 table A 中的行,基于过滤后的行,这些行具有来自 table B 的相同主键列。所以我使用了用于连接主键列的字符串函数,而不是使用 IN。这不是最干净的方法,但它有助于...
DELETE FROM A
WHERE string(PK1,'~',PK2) IN (SELECT string(PK1,'~',PK2) FROM B WHERE columnXZ = 'D')
那个'~'是为了以防万一...
这是我的 table:
Column1 Column2
1 A
2 B
3 B
2 C
4 B
我有以下 SQL 查询来获取 column1 与数字输入列表匹配的所有行,例如“1, 2, 3”:
SELECT * FROM table WHERE column1 IN (1, 2, 3);
这个查询是由一个附加每个数字的程序生成的。 现在我希望 column1 的所有行都匹配一个数字,同时匹配 column2 的一个字符,例如“1和A,2和B,4和B”。 一个可能的查询是:
SELECT * FROM table
WHERE (column1 = 1 and column2 = 'A')
OR (column1 = 2 and column2 = 'B')
OR (column1 = 4 and column2 = 'B')
如果我的列表有几千个值对而我的 table 有几十万个条目怎么办? 有没有更好的方法来获得相同的结果,还是我必须附加一千个 "OR"s?
遗憾的是这不起作用:
SELECT * FROM table
WHERE (column1, column2) IN ((1, 'A'), (2, 'B'), (4, 'B'))
试试这个
WITH CTE1 AS(SELECT column1,column2,ROW_NUMBER() OVER (PARTITION BY column1
ORDER BY column2) AS Row_Count FROM Table_Name)
SELECT column1,column2 FROM CTE1 WHERE Row_Count = 1
这就是我会做的。它通常比使用 OR 的 IN 表现更好,并且在我看来更具可读性。
SELECT * FROM TABLE
INNER JOIN
(
SELECT 1 AS col1, 'a' AS col2 UNION
SELECT 2, 'b' UNION
SELECT 4, 'b'
) AS tbl
ON tbl.col1=TABLE.col1 AND tbl.col2=TABLE.col2
SELECT * FROM table
WHERE (column1, column2)
IN (
SELECT 1 c1, 'A' c2 FROM dual
UNION ALL
SELECT 2, 'B' FROM dual
UNION ALL
SELECT 4, 'B' FROM dual
)
创建具有匹配索引的 table 或 table 变量。加载用户的过滤器,并加入主 table.
试试下面一个
create table #temp (id int, val varchar(1))
insert into #temp (id,val) values (1,'A')
insert into #temp (id,val) values (2,'B')
insert into #temp (id,val) values (3,'B')
insert into #temp (id,val) values (4,'C')
insert into #temp (id,val) values (5,'C')
select * from #temp where val in (
select val from #temp where id in (1,2,3))
好吧,我需要类似的东西,但是对于一个 DELETE 语句,我想在其中删除 table A 中的行,基于过滤后的行,这些行具有来自 table B 的相同主键列。所以我使用了用于连接主键列的字符串函数,而不是使用 IN。这不是最干净的方法,但它有助于...
DELETE FROM A
WHERE string(PK1,'~',PK2) IN (SELECT string(PK1,'~',PK2) FROM B WHERE columnXZ = 'D')
那个'~'是为了以防万一...