如何从具有 JOINed 记录的 SELECT 中获取唯一结果?
How to obtain unique results from a SELECT with JOINed records?
我有这 2 个表,我想查询其中的单个唯一记录:
create table active_pairs
(
id integer,
pair text,
exchange_id integer
);
create table exchanges
(
exchange_id integer,
exchange_full_name text
);
INSERT INTO active_pairs (pair, exchange_id)
VALUES ('London/Berlin', 2),
('London/Berlin', 3),
('Paris/Berlin', 4),
('Paris/Berlin', 3),
('Oslo/Berlin', 2),
('Oslo/Berlin', 6),
('Huston/Berlin', 2);
INSERT INTO exchanges (exchange_id, exchange_full_name)
VALUES (2, 'Exchange 1'),
(3, 'Exchange 2'),
(4, 'Exchange 3'),
(3, 'Exchange 21'),
(2, 'Exchange 12'),
(6, 'Exchange 11'),
(2, 'Exchange 31');
查询列出只有一个 pair
记录的项目:
SELECT * FROM active_pairs ap
INNER JOIN exchanges ce on ap.exchange_id = ce.exchange_id
WHERE ap.exchange_id = :exchangeId
GROUP BY pair, ap.exchange_id, ce.exchange_id, ap.id
HAVING COUNT(ap.pair) = 1
ORDER BY :sort
LIMIT :limit
OFFSET :offset
当我 运行 查询时,我没有得到正确的结果。我只需要获取 Huston/Berlin
,因为这是唯一的记录(请注意,我们还有另一条 exchange_id = 2
的记录)。现在我得到结果 Huston/Berlin
和 'London/Berlin' 与 exchange_id = 2
这是不正确的。
另一个例子:当我查询 exchange_id=4 时,我需要得到空结果,因为如您所见,我有 Paris/Berlin
用于 exchange_id 3
和4
.
你能告诉我如何解决这个问题吗?
没有更多的样本来检查结果,解决方案可以是这样的:
SELECT ap.pair, ap.exchange_id, ce.exchange_id, ap.id FROM active_pairs ap
INNER JOIN exchanges ce on ap.exchange_id = ce.exchange_id
INNER JOIN (SELECT pair FROM active_pairs GROUP BY pair HAVING COUNT(pair) = 1) p on p.pair = ap.pair
WHERE ap.exchange_id = :exchangeId
GROUP BY pair, ap.exchange_id, ce.exchange_id, ap.id
ORDER BY :sort
LIMIT :limit
OFFSET :offset
我猜你只想要你给出的小例子中唯一的活动对名称。
如果我理解正确,这就是你想要做的:
select * from (
select *, count(*) over (partition by pair) as cc from active_pairs
) t join exchanges e on t.exchange_id = e.exchange_id and t.cc=1
db<>fiddle here
SQL
SELECT ap.*, ce.* FROM active_pairs ap
INNER JOIN
(SELECT pair
FROM active_pairs
GROUP BY pair
HAVING COUNT(*) = 1) subq
ON ap.pair = subq.pair
INNER JOIN exchanges ce
ON ap.exchange_id = ce.exchange_id
WHERE ap.exchange_id = :exchangeId
ORDER BY :sort
LIMIT :limit
OFFSET :offset;
说明
子查询 (subq
) 过滤以仅包含出现一次的对名称。然后将其加入 active_pairs
table 以获取 exchange_id
,然后根据您的原始查询加入交易所 table。
演示
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=b3e2dcc5d09401e5bed1f42fdde82a6b
我有这 2 个表,我想查询其中的单个唯一记录:
create table active_pairs
(
id integer,
pair text,
exchange_id integer
);
create table exchanges
(
exchange_id integer,
exchange_full_name text
);
INSERT INTO active_pairs (pair, exchange_id)
VALUES ('London/Berlin', 2),
('London/Berlin', 3),
('Paris/Berlin', 4),
('Paris/Berlin', 3),
('Oslo/Berlin', 2),
('Oslo/Berlin', 6),
('Huston/Berlin', 2);
INSERT INTO exchanges (exchange_id, exchange_full_name)
VALUES (2, 'Exchange 1'),
(3, 'Exchange 2'),
(4, 'Exchange 3'),
(3, 'Exchange 21'),
(2, 'Exchange 12'),
(6, 'Exchange 11'),
(2, 'Exchange 31');
查询列出只有一个 pair
记录的项目:
SELECT * FROM active_pairs ap
INNER JOIN exchanges ce on ap.exchange_id = ce.exchange_id
WHERE ap.exchange_id = :exchangeId
GROUP BY pair, ap.exchange_id, ce.exchange_id, ap.id
HAVING COUNT(ap.pair) = 1
ORDER BY :sort
LIMIT :limit
OFFSET :offset
当我 运行 查询时,我没有得到正确的结果。我只需要获取 Huston/Berlin
,因为这是唯一的记录(请注意,我们还有另一条 exchange_id = 2
的记录)。现在我得到结果 Huston/Berlin
和 'London/Berlin' 与 exchange_id = 2
这是不正确的。
另一个例子:当我查询 exchange_id=4 时,我需要得到空结果,因为如您所见,我有 Paris/Berlin
用于 exchange_id 3
和4
.
你能告诉我如何解决这个问题吗?
没有更多的样本来检查结果,解决方案可以是这样的:
SELECT ap.pair, ap.exchange_id, ce.exchange_id, ap.id FROM active_pairs ap
INNER JOIN exchanges ce on ap.exchange_id = ce.exchange_id
INNER JOIN (SELECT pair FROM active_pairs GROUP BY pair HAVING COUNT(pair) = 1) p on p.pair = ap.pair
WHERE ap.exchange_id = :exchangeId
GROUP BY pair, ap.exchange_id, ce.exchange_id, ap.id
ORDER BY :sort
LIMIT :limit
OFFSET :offset
我猜你只想要你给出的小例子中唯一的活动对名称。
如果我理解正确,这就是你想要做的:
select * from (
select *, count(*) over (partition by pair) as cc from active_pairs
) t join exchanges e on t.exchange_id = e.exchange_id and t.cc=1
db<>fiddle here
SQL
SELECT ap.*, ce.* FROM active_pairs ap
INNER JOIN
(SELECT pair
FROM active_pairs
GROUP BY pair
HAVING COUNT(*) = 1) subq
ON ap.pair = subq.pair
INNER JOIN exchanges ce
ON ap.exchange_id = ce.exchange_id
WHERE ap.exchange_id = :exchangeId
ORDER BY :sort
LIMIT :limit
OFFSET :offset;
说明
子查询 (subq
) 过滤以仅包含出现一次的对名称。然后将其加入 active_pairs
table 以获取 exchange_id
,然后根据您的原始查询加入交易所 table。
演示
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=b3e2dcc5d09401e5bed1f42fdde82a6b