PostgreSQL - 使用聚合函数查询
Posted
技术标签:
【中文标题】PostgreSQL - 使用聚合函数查询【英文标题】:PostgreSQL - Query with aggregate functions 【发布时间】:2014-03-06 10:39:59 【问题描述】:我需要一些关于 PostgreSQL 查询的帮助。 我有 4 个表:customer、organization_complete、entity 和 address。我从每个人那里检索了一些数据,并使用以下查询:
SELECT distinct ON (c.customer_number, trim(lower(o.name)), a.street, a.zipcode, a.area, a.country)
c.xid AS customer_xid, o.xid AS entity_xid, c.customer_number, c.deleted, o.name, o.vat, 'organisation' AS customer_type, a.street, a.zipcode, a.city, a.country
FROM customer c
INNER JOIN organisation_complete o ON (c.xid = o.customer_xid AND c.deleted = 'FALSE')
INNER JOIN entity e ON e.customer_xid = o.customer_xid
INNER JOIN address a ON (a.contact_info_xid = e.contact_info_xid and a.address_type = 'delivery')
WHERE c.account_xid = "<value>"
我得到了按客户编号、姓名、街道、邮政编码、地区和国家(在 DISTINCT ON 语句之后指定的内容)划分的所有客户的不同之处。 我现在需要检索的是在 DB 上具有双行的所有客户的不同,但我还需要检索 customer_xid 和 entity_xid,它们是各个表的主键,因此是唯一的。因此,它们不能包含在聚合函数中。我只需要计算每个不同元组有多少行具有相同的客户编号、名称、街道、邮政编码、地区和国家,并只选择计数大于 1 的元组。 对于每个选定的元组,我还需要随机获取一个 customer_xid 和一个 entity_xid,就像 mysql 在这样的查询中使用 a_key 所做的那样:
SELECT COUNT(*), tab.a_key, tab.b, tab.c from tab
WHERE 1
GROUP BY tab.b
我知道 MySQL 在这方面是个例外,我只是想知道是否有可能在 PostgreSQL 上获得相同的结果。
谢谢,
L.
【问题讨论】:
MySQL 并没有那么坏,即使它不会运行该查询,请更正它。 该查询在 MySQL 上运行... 哇,我很好奇,只是自己测试了查询。它。真的。作品。我知道 MySQL 坏了,但是 那个 坏了?!? @JakubKania 似乎我对你的评论 +1 有点太快了...... 我不会因此而说 MySQL 坏了。以前的 SQL 标准会拒绝该查询,因为您不能在聚合查询中选择不属于 GROUP BY 子句的非聚合字段。但这直到 1992 年都是正确的。现在,根据 SQL-2003 标准,SELECT 和 HAVING 列表中的列在功能上仍然依赖于 GROUP BY 列。如果没有,查询不会被拒绝,您可能只会得到不确定的结果(在我们的例子中是随机选择)。都在这里:dev.mysql.com/doc/refman/5.5/en/group-by-extensions.html @DrColossos 哦,实际上我认为它缺少FROM
子句。由于格式,我没有注意到它。实际上这对 PostgreSQL 也是有效的。万一出现问题,PG 会抛出错误,而不是像 MySQL 那样编造结果。
【参考方案1】:
MySql 中的这个查询使用了一个非标准(见下面的注释)“MySql group by extension”:http://dev.mysql.com/doc/refman/5.0/en/group-by-extensions.html
SELECT COUNT(*), tab.a_key, tab.b, tab.c
from tab
WHERE 1
GROUP BY tab.b
注意:这是在 SQL:2003 标准中定义为 T301 功能依赖项的特性,标准不要求,很多 RDBMS 不支持,包括 PostgreSql(见此链接对于 9.3 版 - 不支持的功能:http://www.postgresql.org/docs/9.3/static/unsupported-features-sql-standard.html)。
上面的查询在PostgreSQL中可以这样表达:
SELECT tab.a_key, tab.b, tab.c,
q.cnt
FROM (
SELECT tab.b,
COUNT(*) As cnt,
MIN(tab.unique_id) As unique_id /* could be also MAX */
from tab
WHERE 1
GROUP BY tab.b
) q
JOIN tab ON tab.unique_id = q.unique_id
其中unique_id
是唯一标识tab
中每一行的列(通常是主键)。
Min 或 Max 函数以伪随机方式从表中选择一行。
【讨论】:
根据 SQL-2003 标准,它不再是非标准扩展,但是谢谢,这是我需要的一个很好的提示:) @lucone83 谢谢你指出,我不知道,我已经更新了我的答案。以上是关于PostgreSQL - 使用聚合函数查询的主要内容,如果未能解决你的问题,请参考以下文章