我有以下声明:
SELECT
IMPORTID,Region,RefObligor,SUM(NOTIONAL) AS SUM_NOTIONAL
From
Positions
Where
ID = :importID
GROUP BY
IMPORTID, Region,RefObligor
Order BY
IMPORTID, Region,RefObligor
表Positions
中存在一些额外的列,我想作为“显示数据”的输出,但我不希望在group by语句中。
这些是Site, Desk
最终输出将包含以下列:
IMPORTID,Region,Site,Desk,RefObligor,SUM(NOTIONAL) AS SUM_NOTIONAL
理想情况下,我希望数据排序如下:
Order BY
IMPORTID,Region,Site,Desk,RefObligor
如何实现这一目标?
答案 0 :(得分:6)
包含不属于GROUP BY子句的列是没有意义的。考虑一下SELECT子句中是否有MIN(X),MAX(Y),其他列(未分组)应该来自哪一行?
如果您的Oracle版本足够新,您可以使用SUM - OVER()来显示针对每个数据行的SUM(分组)。
SELECT
IMPORTID,Site,Desk,Region,RefObligor,
SUM(NOTIONAL) OVER(PARTITION BY IMPORTID, Region,RefObligor) AS SUM_NOTIONAL
From
Positions
Where
ID = :importID
Order BY
IMPORTID,Region,Site,Desk,RefObligor
或者,您需要从Site
,Desk
列中进行汇总
SELECT
IMPORTID,Region,Min(Site) Site, Min(Desk) Desk,RefObligor,SUM(NOTIONAL) AS SUM_NOTIONAL
From
Positions
Where
ID = :importID
GROUP BY
IMPORTID, Region,RefObligor
Order BY
IMPORTID, Region,Min(Site),Min(Desk),RefObligor
答案 1 :(得分:1)
我相信这是
select
IMPORTID,
Region,
Site,
Desk,
RefObligor,
Sum(Sum(Notional)) over (partition by IMPORTID, Region, RefObligor)
from
Positions
group by
IMPORTID, Region, Site, Desk, RefObligor
order by
IMPORTID, Region, RefObligor, Site, Desk;
......但如果没有进一步的信息和/或测试数据,很难说清楚。
答案 2 :(得分:1)
一篇很好的博客文章详细介绍了这个困境:
http://bernardoamc.github.io/sql/2015/05/04/group-by-non-aggregate-columns/
以下是它的一些片段:
假设:
CREATE TABLE games ( game_id serial PRIMARY KEY, name VARCHAR, price BIGINT, released_at DATE, publisher TEXT ); INSERT INTO games (name, price, released_at, publisher) VALUES ('Metal Slug Defense', 30, '2015-05-01', 'SNK Playmore'), ('Project Druid', 20, '2015-05-01', 'shortcircuit'), ('Chroma Squad', 40, '2015-04-30', 'Behold Studios'), ('Soul Locus', 30, '2015-04-30', 'Fat Loot Games'), ('Subterrain', 40, '2015-04-30', 'Pixellore'); SELECT * FROM games; game_id | name | price | released_at | publisher ---------+--------------------+-------+-------------+---------------- 1 | Metal Slug Defense | 30 | 2015-05-01 | SNK Playmore 2 | Project Druid | 20 | 2015-05-01 | shortcircuit 3 | Chroma Squad | 40 | 2015-04-30 | Behold Studios 4 | Soul Locus | 30 | 2015-04-30 | Fat Loot Games 5 | Subterrain | 40 | 2015-04-30 | Pixellore (5 rows)
试图得到这样的东西:
SELECT released_at, name, publisher, MAX(price) as most_expensive FROM games GROUP BY released_at;
但由于汇总时含糊不清,因此未添加name
和publisher
...
让我们说清楚:
Selecting the MAX(price) does not select the entire row.
数据库无法知道,何时无法给出正确答案 给定查询的时间应该给我们一个错误,那就是它 确实!
好的......好的......这不是那么简单,我们能做些什么?
使用inner join
获取其他列
SELECT g1.name, g1.publisher, g1.price, g1.released_at
FROM games AS g1
INNER JOIN (
SELECT released_at, MAX(price) as price
FROM games
GROUP BY released_at
) AS g2
ON g2.released_at = g1.released_at AND g2.price = g1.price;
或者使用left outer join
获取其他列,然后按重复列的NULL进行过滤...
SELECT g1.name, g1.publisher, g1.price, g2.price, g1.released_at
FROM games AS g1
LEFT OUTER JOIN games AS g2
ON g1.released_at = g2.released_at AND g1.price < g2.price
WHERE g2.price IS NULL;
希望有所帮助。