使用 DISTINCT 显示唯一项
Use DISTINCT to display unique items
我有 2 个表,我想查询和显示数据差异:
CREATE TABLE order_splits_config (
id INT,
pair_id INT
);
CREATE TABLE active_pairs (
id INT,
pair VARCHAR(30),
exchange_active boolean,
exchange_id INT
);
INSERT INTO order_splits_config(id, pair_id)
VALUES (1, 83);
INSERT INTO order_splits_config(id, pair_id)
VALUES (2, 58);
INSERT INTO order_splits_config(id, pair_id)
VALUES (34, 34);
INSERT INTO active_pairs(id, pair, exchange_active, exchange_id)
VALUES (1, 'US/EN', true, 2);
INSERT INTO active_pairs(id, pair, exchange_active, exchange_id)
VALUES (2, 'GB/UK', true, 3);
INSERT INTO active_pairs(id, pair, exchange_active, exchange_id)
VALUES (2, 'FR/EU', true, 4);
我用这个查询来查询差异:
SELECT b.id, b.pair, b.exchange_id
FROM order_splits_config a
FULL OUTER JOIN active_pairs b
ON a.pair_id = b.id
WHERE a.pair_id IS NULL
OR b.id IS NULL
AND b.exchange_active = 'true';
这会打印很多行,例如(数据只是为了举例):
#,pair,id,exchange_id
1, US/EN,332,1
2, GB/UK,112,1
3, GB/UK,113,1
4, FR/EU,221,5
5, FR/EU,183,2
...
如何使用 DISTINCT
才能从 pair
唯一的查询中获得结果?
FIDDLE: https://www.db-fiddle.com/f/4D6VfqysPCWhQnh8zaFBps/2
您只有 select 列从 table active_pairs
开始。
加入 a.pair_id = b.id
后,条件 a.pair_id IS NULL
仅当 table order_splits_config AS a
中没有匹配行时才为真,更有效的表述为 NOT EXISTS
而不是 FULL JOIN
.
至于 b.id IS NULL AND b.exchange_active = 'true'
:同样,b.id
只能是 NULL
对于 a
的行,其中没有找到匹配的 b
- 在这种情况下b.exchange_active
永远不可能是真的。因此,该子句有效地消除了 a
中刚刚由 FULL JOIN
添加的所有行,这些行将在结果中显示为所有 NULL 值,因为只有 b
中的列。简而言之:不要FULL JOIN
开始。
如果active_pairs.pair
定义为UNIQUE
,归结为:
SELECT id, pair, exchange_id
FROM active_pairs b
WHERE NOT EXISTS (SELECT FROM order_splits_config a WHERE a.pair_id = b.id);
如果 active_pairs.pair
未定义 UNIQUE
,简单的解决方案是 DISTINCT ON
:
SELECT DISTINCT ON (pair)
id, pair, exchange_id
FROM active_pairs b
WHERE NOT EXISTS (SELECT FROM order_splits_config a WHERE a.pair_id = b.id);
db<>fiddle here
从 pair
的每组重复中,你会得到一个 任意 的选择。
对于 确定性 选择,定义要选择的内容并相应地添加 ORDER BY
子句。示例:要获得最小的 id
,请添加:
...
ORDER BY pair, id;
还为迄今为止未排序的结果添加排序顺序。
如果 order_splits_config
不是非常小,请在 (pair_id)
上建立索引以加快速度。
可能有 much 大 active_pairs
table 更快的解决方案,具体取决于未公开的信息,主要是列 pair
的基数(有多少重复值)。
参见:
- Select first row in each GROUP BY group?
- Select rows which are not present in other table
- Optimize GROUP BY query to retrieve latest row per user
我有 2 个表,我想查询和显示数据差异:
CREATE TABLE order_splits_config (
id INT,
pair_id INT
);
CREATE TABLE active_pairs (
id INT,
pair VARCHAR(30),
exchange_active boolean,
exchange_id INT
);
INSERT INTO order_splits_config(id, pair_id)
VALUES (1, 83);
INSERT INTO order_splits_config(id, pair_id)
VALUES (2, 58);
INSERT INTO order_splits_config(id, pair_id)
VALUES (34, 34);
INSERT INTO active_pairs(id, pair, exchange_active, exchange_id)
VALUES (1, 'US/EN', true, 2);
INSERT INTO active_pairs(id, pair, exchange_active, exchange_id)
VALUES (2, 'GB/UK', true, 3);
INSERT INTO active_pairs(id, pair, exchange_active, exchange_id)
VALUES (2, 'FR/EU', true, 4);
我用这个查询来查询差异:
SELECT b.id, b.pair, b.exchange_id
FROM order_splits_config a
FULL OUTER JOIN active_pairs b
ON a.pair_id = b.id
WHERE a.pair_id IS NULL
OR b.id IS NULL
AND b.exchange_active = 'true';
这会打印很多行,例如(数据只是为了举例):
#,pair,id,exchange_id
1, US/EN,332,1
2, GB/UK,112,1
3, GB/UK,113,1
4, FR/EU,221,5
5, FR/EU,183,2
...
如何使用 DISTINCT
才能从 pair
唯一的查询中获得结果?
FIDDLE: https://www.db-fiddle.com/f/4D6VfqysPCWhQnh8zaFBps/2
您只有 select 列从 table active_pairs
开始。
加入 a.pair_id = b.id
后,条件 a.pair_id IS NULL
仅当 table order_splits_config AS a
中没有匹配行时才为真,更有效的表述为 NOT EXISTS
而不是 FULL JOIN
.
至于 b.id IS NULL AND b.exchange_active = 'true'
:同样,b.id
只能是 NULL
对于 a
的行,其中没有找到匹配的 b
- 在这种情况下b.exchange_active
永远不可能是真的。因此,该子句有效地消除了 a
中刚刚由 FULL JOIN
添加的所有行,这些行将在结果中显示为所有 NULL 值,因为只有 b
中的列。简而言之:不要FULL JOIN
开始。
如果active_pairs.pair
定义为UNIQUE
,归结为:
SELECT id, pair, exchange_id
FROM active_pairs b
WHERE NOT EXISTS (SELECT FROM order_splits_config a WHERE a.pair_id = b.id);
如果 active_pairs.pair
未定义 UNIQUE
,简单的解决方案是 DISTINCT ON
:
SELECT DISTINCT ON (pair)
id, pair, exchange_id
FROM active_pairs b
WHERE NOT EXISTS (SELECT FROM order_splits_config a WHERE a.pair_id = b.id);
db<>fiddle here
从 pair
的每组重复中,你会得到一个 任意 的选择。
对于 确定性 选择,定义要选择的内容并相应地添加 ORDER BY
子句。示例:要获得最小的 id
,请添加:
...
ORDER BY pair, id;
还为迄今为止未排序的结果添加排序顺序。
如果 order_splits_config
不是非常小,请在 (pair_id)
上建立索引以加快速度。
可能有 much 大 active_pairs
table 更快的解决方案,具体取决于未公开的信息,主要是列 pair
的基数(有多少重复值)。
参见:
- Select first row in each GROUP BY group?
- Select rows which are not present in other table
- Optimize GROUP BY query to retrieve latest row per user