【发布时间】:2016-03-01 02:38:31
【问题描述】:
我有两个表:parcel 和 structure,它们之间是一对多的关系:structure.parcel_id 指向 parcel.id。
我想选择所有单个结构。我目前的解决方案有效,但非常怪诞:
SELECT
max(column_1),
max(column_2),
max(column_3),
...
(twenty+ columns)
FROM structure
GROUP BY parcel_id
HAVING count(structure.id) = 1;
因为structure.id 不可为空并且上面的HAVING 子句,根据定义,每个组中只有一行。不幸的是 Postgres 没有意识到这一点,所以如果我说:
SELECT *
FROM structure
GROUP BY parcel_id
HAVING count(structure.id) = 1;
然后我得到关于需要对列使用聚合函数的预期错误。我用任意的max() 函数解决了这个问题,但这会让试图理解代码的其他人感到困惑,它迫使我明确列出所有列,这意味着我必须重新潜入并编辑这段代码添加列。 (不幸的是,这在我的环境中经常发生。)
我有这个替代解决方案,它解决了我的大部分问题:
SELECT * FROM STRUCTURE
WHERE id IN (
SELECT
max(id) as id
FROM structure
GROUP by structure.parcel_id
HAVING count(structure.id) = 1
);
但这显然给我的查询增加了不必要的缓慢,由于查询的频率和表的大小,我想避免这种情况。
This question 与我的要求非常相似,但它会抓取每个组的第一行,而不是第一行(也是唯一的)单数组。
有没有优雅的方法来解决这个问题?
每个请求的示例数据:
structure表:
id | parcel_id | column_1 | column_2 | ...
------------------------------------------
1 | 536 | ... | .... | ...
2 | 536 | ... | .... | ...
3 | 537 | ... | .... | ...
4 | 538 | ... | .... | ...
5 | 538 | ... | .... | ...
6 | 539 | ... | .... | ...
7 | 540 | ... | .... | ...
8 | 541 | ... | .... | ...
9 | 541 | ... | .... | ...
想要的结果:
id | parcel_id | column_1 | column_2 | ...
------------------------------------------
3 | 537 | ... | .... | ...
6 | 539 | ... | .... | ...
7 | 540 | ... | .... | ...
请注意,537、539 和 540 是唯一不重复的 parcel_id。
两个表都有约 150 万行和约 25 列。
【问题讨论】:
-
能否请您发布一些有代表性的样本数据和想要的结果。
-
所以,
structure表有 150 万行。parcel表中有多少行?structure表中有多少个地块只有一个对应的行?换句话说,最终查询将返回多少行? -
我不太熟悉 SQL,所以在评论中发表我的建议。您可以将自联接用作此 'SELECT S1.* FROM STRUCTURE S1, STRUCTURE S2 WHERE S1.parcel_id = S2.parcel_id GROUP BY S2.parcel_id HAVING count(S2.parcel_id) = 1'
标签: sql postgresql aggregate postgresql-performance