SQL:如何同时使用 DECODE 和 COUNT 函数

str*_*del 1 sql oracle pivot group-by count

我正在做作业,但我们还没有学过 DECODE 函数,只学过 CASE。本周的单元是关于使用聚合函数。以下是我的作业问题以及我的教授想要的结果 -

“下面两道题非常有挑战性(需要使用DECODE函数来完成)。

  1. 创建一个查询,显示员工总数以及 1980 年、1981 年、1982 年和 1987 年雇用的员工总数。提供适当的列标题。(5分)

    Total 1980  1981  1982  1987
    ----- ----- ----- ----- -----
       14     1    10     1     2
    
    Run Code Online (Sandbox Code Playgroud)

这是我在服务器中输入的函数以及结果。我只尝试了1980年,所以我不浪费时间,但我还需要1981年、1982年和1987年-

SELECT COUNT(ename) AS "Total",
 COUNT(DECODE(hiredate, '80', '1980'))
 FROM emp;

Total COUNT(DECODE(HIREDATE,'80','1980'))
----- -----------------------------------
   14                                   0
Run Code Online (Sandbox Code Playgroud)

这是“雇用日期”列的数据类型 -

HIREDATE
---------
17-NOV-81
01-MAY-81
09-JUN-81
02-APR-81
28-SEP-81
20-FEB-81
08-SEP-81
03-DEC-81
22-FEB-81
03-DEC-81
17-DEC-80

HIREDATE
---------
09-DEC-82
12-JAN-83
23-JAN-82
Run Code Online (Sandbox Code Playgroud)

已选择 14 行。

感谢任何人的帮助!

MT0*_*MT0 5

假设该hiredate列的数据类型为DATE.

让我们不使用它DECODE并使用PIVOT它:

甲骨文设置

CREATE TABLE emp ( ename, hiredate ) AS
  SELECT 'A', DATE '1980-01-01' FROM DUAL UNION ALL
  SELECT 'B', DATE '1981-01-01' FROM DUAL UNION ALL
  SELECT 'C', DATE '1981-02-01' FROM DUAL UNION ALL
  SELECT 'D', DATE '1981-03-01' FROM DUAL UNION ALL
  SELECT 'E', DATE '1981-04-01' FROM DUAL UNION ALL
  SELECT 'F', DATE '1981-05-01' FROM DUAL UNION ALL
  SELECT 'G', DATE '1981-06-01' FROM DUAL UNION ALL
  SELECT 'H', DATE '1981-07-01' FROM DUAL UNION ALL
  SELECT 'I', DATE '1981-08-01' FROM DUAL UNION ALL
  SELECT 'J', DATE '1981-09-01' FROM DUAL UNION ALL
  SELECT 'K', DATE '1981-10-01' FROM DUAL UNION ALL
  SELECT 'L', DATE '1982-01-01' FROM DUAL UNION ALL
  SELECT 'M', DATE '1987-01-01' FROM DUAL UNION ALL
  SELECT 'N', DATE '1987-02-01' FROM DUAL;
Run Code Online (Sandbox Code Playgroud)

询问

SELECT *
FROM   (
  SELECT EXTRACT( YEAR FROM hiredate ) AS hireyear,
         COUNT(*) OVER () AS "Total"
  FROM   emp
)
PIVOT ( COUNT(*) FOR hireyear IN ( 1980, 1981, 1982, 1987 ) )
Run Code Online (Sandbox Code Playgroud)

输出

总计 | 1980 | 1981 | 1982 | 1987年
----: | ---: | ---: | ---: | ---:
   14 | 14 1 | 10 | 10 1 | 2

查询2

您还可以使用以下方法进行操作CASE

Total | 1980 | 1981 | 1982 | 1987
----: | ---: | ---: | ---: | ---:
   14 |    1 |   10 |    1 |    2

查询3

或者与DECODE.

SELECT COUNT(*) AS "Total",
       COUNT(
         CASE
         WHEN hiredate >= DATE '1980-01-01' AND hiredate < DATE '1981-01-01'
         THEN hiredate
         END
       ) AS "1980",
       COUNT(
         CASE
         WHEN hiredate >= DATE '1981-01-01' AND hiredate < DATE '1982-01-01'
         THEN hiredate
         END
       ) AS "1981",
       COUNT(
         CASE
         WHEN hiredate >= DATE '1982-01-01' AND hiredate < DATE '1983-01-01'
         THEN hiredate
         END
       ) AS "1982",
       COUNT(
         CASE
         WHEN hiredate >= DATE '1987-01-01' AND hiredate < DATE '1988-01-01'
         THEN hiredate
         END
       ) AS "1987"
FROM   emp
Run Code Online (Sandbox Code Playgroud)

注意:当你计数时,你会计算传递给的值COUNT不是 -NULL因此函数可以在匹配时DECODE返回任何非值并且它会被计数;NULL相反,只要返回的值COUNT是,这是当您不提供额外的偶数参数时的NULL默认值,那么它就不会计算该行。DECODE

所以你可以使用任何文字值。就像一个字符串:

SELECT COUNT(*) AS "Total",
       COUNT( DECODE( EXTRACT( YEAR FROM hiredate ), 1980, 'anything here' ) ) AS "1980",
       COUNT( DECODE( EXTRACT( YEAR FROM hiredate ), 1981, 'anything here' ) ) AS "1981",
       COUNT( DECODE( EXTRACT( YEAR FROM hiredate ), 1982, 'anything here' ) ) AS "1982",
       COUNT( DECODE( EXTRACT( YEAR FROM hiredate ), 1987, 'anything here' ) ) AS "1987"
FROM   emp
Run Code Online (Sandbox Code Playgroud)

或一个数字

COUNT( DECODE( EXTRACT( YEAR FROM hiredate ), 1980, 'anything here' ) ) AS "1980"
Run Code Online (Sandbox Code Playgroud)

甚至hiredate列(如果它的年份是 1980 那么你就知道它不是NULL):

COUNT( DECODE( EXTRACT( YEAR FROM hiredate ), 1980, 1 ) ) AS "1980"
Run Code Online (Sandbox Code Playgroud)

如果您想明确DECODE不匹配时的返回值,请添加一个额外的NULL参数:

COUNT( DECODE( EXTRACT( YEAR FROM hiredate ), 1980, hiredate ) ) AS "1980"
Run Code Online (Sandbox Code Playgroud)

db<>在这里摆弄