SQL - 选择最常见的值

时间:2017-06-10 20:18:40

标签: sql oracle top-n

我坚持这一点,我希望有人可以帮助我:

SELECT max(SELECT count(TO_CHAR(hire_date, 'DAY')) 
           FROM employees 
           GROUP BY TO_CHAR(hire_date, 'DAY')) 
FROM employees;

           *
ERROR at line 1:
ORA-00936: missing expression

子查询的输出如下:

TO_CHAR(HIRE_DATE,'DAY')         COUNT(TO_CHAR(HIRE_DATE,'DAY'))
---------------------------------------- -------------------------------
THURSDAY                                   3
SATURDAY                                   3
WEDNESDAY                                  4
MONDAY                                     1
SUNDAY                                     3
TUESDAY                                    6

我只想选择TUESDAY

7 个答案:

答案 0 :(得分:1)

您可以通过将分析函数RANK()添加到内部查询的SELECT子句来完成此操作。然后在外部查询中选择排名为1的行。这将产生所有“并列第一天”(单个获胜者或并列第一名)。

https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions123.htm(查找 analytic 版本!)

to_char(....)看起来很丑陋,但由于它是确定性的,因此Oracle只计算一次(即使它在四个地方使用)。

select dy, ct
from   (
         select   to_char(hire_date, 'DAY') as dy,
                  count(to_char(hire_date, 'DAY')) as ct,
                  rank() over (order by count(to_char(hire_date, 'DAY')) desc) as rk
         from     hr.employees
         group by to_char(hire_date, 'DAY')
       )
where  rk = 1
;

答案 1 :(得分:0)

问题中的子查询不会产生描述的输出。 尝试使用具有的子查询。

select max( total ) from (
    SELECT TO_CHAR(HIRE_DATE,'DAY') day 
    , count(TO_CHAR(hire_date, 'DAY')) total
    FROM employees 
    GROUP BY TO_CHAR(hire_date, 'DAY')
) daysTotals

在oracle上未经测试。

答案 2 :(得分:0)

您可以使用HAVING - 子句中的子查询解决此问题:

select TO_CHAR(hire_date, 'DAY') as day, count(TO_CHAR(hire_date, 'DAY')) as cnt
FROM employees 
GROUP BY TO_CHAR(hire_date, 'DAY')) 
HAVING count(TO_CHAR(hire_date, 'DAY')) >= ALL (
           SELECT count(TO_CHAR(hire_date, 'DAY')) 
           FROM employees 
           GROUP BY TO_CHAR(hire_date, 'DAY')

答案 3 :(得分:0)

试试这个..想法是使用内部内部联接来获得最多招聘人数的所有日子。

select hiredays.* from (
    select max( total ) total from (
        SELECT TO_CHAR(HIRE_DATE,'DAY') day 
        , count(TO_CHAR(hire_date, 'DAY')) total
        FROM employees 
        GROUP BY TO_CHAR(hire_date, 'DAY')) 
    ) daysTotals
) maximum
inner join (
    SELECT TO_CHAR(HIRE_DATE,'DAY') day 
    , count(TO_CHAR(hire_date, 'DAY')) total
    FROM employees 
    GROUP BY TO_CHAR(hire_date, 'DAY'))
) hiredays
on hiredays.total = maximum.total

在Oracle上未经测试。

答案 4 :(得分:0)

使用子查询查找一周中唯一的招聘日期和相关的计数。然后,使用RANK函数确定哪一个是顶部。然后,选择排名最高的那一天。

WITH HireSummary AS (
     SELECT TO_CHAR(hire_date, 'DAY') AS HireDay, 
            COUNT(TO_CHAR(hire_date, 'DAY')) AS HireDayCount 
     FROM employees 
     GROUP BY TO_CHAR(hire_date, 'DAY')),
RankedSummary AS (
     SELECT HireDay, HireDayCount, RANK() OVER (ORDER BY HireDayCount DESC) AS DayRank
     FROM HireSummary)
SELECT HireDay FROM RankedSummary WHERE DayRank = 1;

这样做的好处是,如果您在周二和周三都雇用了6个人,那么它将同时返回。

但是,如果您只想获得上述案例的单一答案,请将SELECT HireDay转为SELECT MAX(HireDay)

答案 5 :(得分:0)

使用FIRST表达式时,即使没有子查询,也可以执行此操作:

SELECT 
    MAX(COUNT(hire_date)) KEEP (DENSE_RANK LAST ORDER BY COUNT(hire_date)),
    MAX(TO_CHAR(hire_date, 'DAY')) KEEP (DENSE_RANK LAST ORDER BY COUNT(hire_date))
FROM EMPLOYEES
GROUP BY TO_CHAR(hire_date, 'DAY');

但请注意,这只会返回一天。如果你有几天与相同数量的员工,你只会看到其中一个。

答案 6 :(得分:-1)

您的查询没有意义,但您描述了您想要的内容,并且已经有答案可以回答这个问题。我想你想做点什么

SELECT max(empcount)
from (SELECT count(TO_CHAR(hire_date, 'DAY'))  empcount
    FROM employees 
    GROUP BY TO_CHAR(hire_date, 'DAY')) 
;

会返回

6

我不会尝试在此处编写适当的select语句,而是专注于错误消息。

您在选择列表中使用select语句。这称为标量子查询表达式。 Database SQL Language Reference, subsection: Scalar Subquery Expressions说:

  

您可以在调用表达式(expr)的大多数语法中使用标量子查询表达式。在所有情况下,标量子查询必须用自己的括号括起来,即使它的语法位置已经将它放在括号内(例如,当标量子查询用作内置函数的参数时)。

所以错误信息

ORA-00936: missing expression

是对的。在max(解析器期望表达式而不是关键字select之后。 因此,您必须添加一对额外的括号:一个用于max函数,另一个用于select语句: 但现在他发表了声明

SELECT max((SELECT count(TO_CHAR(hire_date, 'DAY')) 
    FROM employees 
    GROUP BY TO_CHAR(hire_date, 'DAY')))
    FROM employees;

加注

ORA-01427: single-row subquery returns more than one row

正如预期的那样,因为你的subselect返回多行。

(Oracle Database 12c企业版12.2.0.1.0版 - 64位)