Postgres:不同但仅一栏


120

我在pgsql上有一张表,上面有名字(有1个以上mio行),但是我也有很多重复项。我选择3个字段:idnamemetadata

我想用ORDER BY RANDOM()和随机选择它们LIMIT 1000,所以我要做很多步骤来在PHP脚本中节省一些内存。

但是我该怎么做,所以它只给我一个名称上没有重复的列表。

例如[1,"Michael Fox","2003-03-03,34,M,4545"]将返回但不返回[2,"Michael Fox","1989-02-23,M,5633"]。名称字段是最重要的,并且每次执行选择时列表中的名称字段都必须唯一,并且名称字段必须是随机的。

我尝试过GROUP BY name,但bu希望我也可以在id或中继功能中包含id和元数据GROUP BY,但我不想以某种方式对其进行过滤。

任何人都知道如何获取许多列,但在一个列上只做一个不同的列?

Answers:


225

仅在一个(或n)列上进行区分:

select distinct on (name)
    name, col1, col2
from names

这将返回包含名称的任何行。如果要控制将返回哪几行,则需要订购:

select distinct on (name)
    name, col1, col2
from names
order by name, col1

按col1排序时将返回第一行。

distinct on

SELECT DISTINCT ON(expression [,...])仅保留给定表达式求值相等的每组行的第一行。使用与ORDER BY相同的规则来解释DISTINCT ON表达式(请参见上文)。请注意,除非使用ORDER BY来确保所需的行首先出现,否则每个集合的“第一行”都是不可预测的。

DISTINCT ON表达式必须与最左边的ORDER BY表达式匹配。ORDER BY子句通常将包含其他表达式,这些表达式确定每个DISTINCT ON组中所需的行优先级。


订购时要注意。我之所以没有包含它,是因为他们提到要随机排序,但是无论如何都要提一下。
Craig Ringer 2013年

order by name必需的吗?会产生不同的结果order by col1吗?
Elliot Chance

1
@elliot是name必须的。检查distinct on手册。
Clodoaldo Neto 2015年

1
我希望TSQL团队可以提供这种明智的方法。
JTW

请添加相应的PostgreSQL 参考
Ogaga Uzoh

17

任何人都知道如何获取许多列,但在一个列上只做一个不同的列?

您需要DISTINCT ON子句

您没有提供示例数据或完整的查询,因此我没有任何东西可向您显示。您想要编写类似以下内容的内容:

SELECT DISTINCT ON (name) fields, id, name, metadata FROM the_table;

这将返回一组不可预测(但不是“随机”)行。如果要使其可预测,请添加ORDER BY每个Clodaldo的答案。如果要使其真正随机,则需要ORDER BY random()


只需注意此DISTINCT ON子句,就只能对同一事物进行ORDER BY +更多。因此,如果您说DISTINCT ON(name),则必须按名称ORDER BY名称,然后再选择其他名称。不太理想。
凯文·帕克

凯文,您可以在外部查询中使用CTE或FROM子查询以及ORDER BY
Craig Ringer

是的,然后观察性能如何...将搜索索引空间中的所有可能结果。正是由于posgres无法处理不同的区分/排序,所以将具有正确索引的10-20ms查询变成了900ms查询。甚至与外部查询的顺序无关紧要,它都将使用内部子查询中的索引来首先找到匹配项,然后重新排序。很高兴在dba.stackexchange.com/questions/260852/上
凯文·帕克

4
SELECT NAME,MAX(ID) as ID,MAX(METADATA) as METADATA 
from SOMETABLE
GROUP BY NAME

2
请注意:可能不会返回“一起”的ID值或元数据值
a_horse_with_no_name 2013年

@Novum否。这意味着它从Michael的一行中获取id值,并从另一行中获取元数据,因为它被要求提供Michael的最大值。
Clodoaldo Neto 2013年

是的,这很大程度上取决于OP的实际数据使用,我对此一无所知。您可能需要使用MIN或其他名称。刚刚演示了如何在GROUP BY子句中包括字段。
David Jashi 2013年

这不是一个很好的解决方案,因为来自不同行的不同值将混合在一起。
Elliot Chance
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.