提供表格
CREATE TABLE data(
irs_number VARCHAR (50),
mop_up INTEGER,
ou VARCHAR (50)
);
我如何返回所有匹配的记录...
irs_number
至少具有一个相同的值,并且mop_up
个具有相同irs_number
的用户必须设置为1
并且ou
的值不相同,即只返回与相同的irs_number
不匹配的那些值。 ...,以便返回所有irs_numbers
(不仅是满足条件的一个-参见下面的示例)。
我尝试了此操作,但是查询无法在合理的时间内完成:
SELECT irs_number, mop_up, ou
FROM data outer_data
WHERE (SELECT count(*)
FROM data inner_data
WHERE inner_data.irs_number = outer_data.irs_number
AND inner_data.mop_up = 1 OR outer_data.mop_up = 1
AND inner_data.ou <> outer_data.ou
);
以及此处描述的重复计数的变化形式:How to find duplicate records in PostgreSQL-它们将始终仅返回重复计数,但不会应用适当的过滤器。
修改:
示例数据:
INSERT INTO data VALUES
('0001', 1, 'abc'),
('0001', 0, 'abc'),
('0001', 0, 'cde'),
('0001', 0, 'abc'),
('0002', 1, 'abc'),
('0002', 0, 'abc'),
('0003', 0, 'abc'),
('0003', 0, 'xyz')
;
SQLFiddle:http://sqlfiddle.com/#!17/be28f
理想情况下,查询应返回:
irs_number mop_up ou
-----------------------
0001 1 abc
0001 0 abc
0001 0 cde
0001 0 abc
(顺序不重要)
表示它应返回所有匹配irs_number
与以上条件的行。
答案 0 :(得分:1)
我认为此联接可以做到:
SELECT * FROM data
WHERE irs_number in (
SELECT irs_number
FROM data d
WHERE EXISTS (SELECT 1
FROM data
WHERE irs_number = d.irs_number
AND (mop_up = 1 OR d.mop_up = 1)
AND ou <> d.ou
)
)
请参见demo
答案 1 :(得分:1)
您应该可以使用简单的exists
子句来做到这一点:
SELECT irs_number, mop_up, ou
FROM data d
WHERE EXISTS (SELECT 1
FROM data d2
WHERE d2.irs_number = d.irs_number AND
d2.mop_up = 1 AND
d2.ou <> d.ou
);
编辑:
以上内容误解了这个问题。它假定mop_up = 1
必须位于不同 ou
上。当我阅读问题时,这是模棱两可的,但似乎不是您想要的。因此,两个exists
解决了这个问题:
SELECT irs_number, mop_up, ou
FROM data d
WHERE EXISTS (SELECT 1
FROM data d2
WHERE d2.irs_number = d.irs_number AND
d2.mop_up = 1
) AND
EXISTS (SELECT 1
FROM data d2
WHERE d2.irs_number = d.irs_number AND
d2.ou <> d.ou
);
Here是db <>小提琴。
这两种解决方案都将能够利用(irs_number, mop_up, ou)
上的索引。