查询收集返回多个值的子查询的最大值

Posted

技术标签:

【中文标题】查询收集返回多个值的子查询的最大值【英文标题】:Query gathering the max value of a subquery returning multiple values 【发布时间】:2019-05-13 11:51:17 【问题描述】:

我在 Oracle 数据库上遇到了另一个关于 SQL 查询的问题,我无法解决。我有 3 张桌子,其中两张收集有关某些用户和结构的信息,另一张收集有关结构的预订。多亏了一个查询,我应该能够显示对特定城市的结构进行最大预订次数的用户姓名,在本例中为“Torre annunziata”。

为了实现这一点,我创建了一个查询,其目标是显示一个表格,该表格为每个用户显示他为我之前提到的结构所做的预订量。

SELECT P.UTENTE, COUNT(Case when S.Citta = 'Torre Annunziata' then 1 else null end) as cnt
FROM PRENOTAZIONI P JOIN STRUTTURE S ON P.STRUTTURA = S.CODICE JOIN UTENTI ON P.UTENTE = UTENTI.CF
GROUP BY P.UTENTE;

这给出了预期的结果:table1

现在我尝试了以下方法:

SELECT UTENTI.NOME, UTENTI.COGNOME, MAX(cnt)
FROM UTENTI JOIN ( SELECT P.UTENTE, COUNT(Case when S.Citta = 'Torre Annunziata' then 1 else null end) as cnt
                    FROM PRENOTAZIONI P JOIN STRUTTURE S ON P.STRUTTURA = S.CODICE JOIN UTENTI ON P.UTENTE = UTENTI.CF
                    GROUP BY P.UTENTE) L ON UTENTI.CF = L.UTENTE
GROUP BY UTENTI.COGNOME, UTENTI.NOME;

但这会返回与上一个查询相同的结果(每个人的姓名)。

根据我的请求,我期望的结果是用户 0000000002 的姓名和姓氏,可能没有显示最大值。

我知道 MAX 函数返回每个用户的值,因此我搜索了 oracle 的替代方案,但我找不到可以应用于我的问题的解决方案。我希望有人能帮助我。 在此先感谢,并为我的英语不好感到抱歉。

【问题讨论】:

【参考方案1】:

你不想聚合。请改用窗口函数。如果你想要领带:

SELECT u.*
FROM UTENTI u JOIN
     (SELECT P.UTENTE, u.NOME, u.COGNOME, COUNT(*) as cnt,
             RANK() OVER (ORDER BY COUNT(*) DESC) as seqnum
      FROM PRENOTAZIONI P JOIN
           STRUTTURE S
           ON P.STRUTTURA = S.CODICE JOIN
           UTENTI u
           ON P.UTENTE = u.CF
      WHERE S.Citta = 'Torre Annunziata'
      GROUP BY P.UTENTE, u.NOME, u.COGNOME
     ) u
WHERE seqnum = 1;

注意事项:

您不需要JOINUTENTI 两次。 过滤条件可以放在WHERE子句中。 如果您只想要一行,请使用 ROW_NUMBER() 而不是 RANK(),即使存在平局也是如此。

【讨论】:

这按预期工作,除了我需要更改 JOIN 期望 ON 关键字的最后一部分。我双重加入,因为程序无法识别 UTENTI 表。我过滤了 COUNT 函数,因为我必须执行类似的查询,并且使用 WHERE 子句过滤从查询中排除了 0 个结果,而我需要它们显示。最后,感谢您阐明了 RANK 函数的目的并解决了问题。

以上是关于查询收集返回多个值的子查询的最大值的主要内容,如果未能解决你的问题,请参考以下文章

使用两个可以返回多个值的子查询的 SQL 之间的语句

列中有多个值的子查询[关闭]

子查询优化

子查询

SQL ---子查询

数据库子查询