我有两个表JOB和EMP;值是这样的
CREATE TABLE JOB (JOBID SMALLINT UNIQUE NOT NULL,JOBNAME CHAR(15));
CREATE TABLE EMP(EMPID SMALLINT, JOBID SMALLINT, SAL SMALLINT, CITYID
SMALLINT,YEAR SMALLINT,STATUS CHAR(1));
INSERT INTO JOB(JOBID, JOBNAME) VALUES
( 1, 'DEVELOPMENT'),
(2, 'DEVELOPMENT'),
(3,'TESTING'),
(4,'TESTING'),
(7,'TESTING'),
(9,'RESEARCH'),
(8,'HR');
INSERT INTO EMP (EMPID , JOBID, SAL,CITYID,YEAR,STATUS) VALUES
( 100,1,1000,10,2015,'A'),
( 200,2,2000,10.2015,'A'),
( 300,1,2500,20,2015,'E'),
( 400,3,1000,10,2016,'A'),
( 500,6,3000,10,2015,'E'),
( 600,8,1000,30,2015,'A'),
( 700,8,2000,10,2015,'A'),
( 800,9,1500,20,2015,'A')
;
我想显示所有工作名称计数和平均工资;作业名称(如果不存在作业ID)则显示0
对于给定的输入cityid,YEAR和STATUS(Emp表),获取每个作业名的所有jobid(来自job表),并在Emp表中匹配(如果存在显示计数(Emp表中存在的jobid的数量)),否则为avgsal 0表示计数和平均值。
对于Cityid的2015年10和20年状态为“ A”,输出应类似于
Cityid jobname count avg-sal
10 development 2 1500
10 TESTING 0 0
10 RESEARCH 0 0
10 HR 1 2000
10 total 3 1666.66
20 development 0 0
20 Testing 0 0
20 Research 1 1500
20 HR 0 0
20 Total 1 2500
Grand Total 4 1625
我尝试通过联接,但是无法正常工作; 使用join或Cursor更好吗?
答案 0 :(得分:1)
您可以像下面这样使用GROUP BY ROLLUP
。
SELECT CASE
WHEN cityid IS NOT NULL
AND jobname IS NULL THEN 'Total'
WHEN cityid IS NULL
AND jobname IS NULL THEN 'Grand Total'
ELSE Cast(cityid AS VARCHAR(100))
END CityId,
jobname,
[count],
[avg_sal]
FROM (SELECT e.cityid,
j.jobname,
Count(*) [Count],
Avg(sal) [Avg_Sal]
FROM job J
INNER JOIN emp E
ON e.jobid = j.jobid
GROUP BY rollup ( e.cityid, j.jobname )) t
编辑:对于所有JOBNAME
,您都需要使用CROSS JOIN
来获取所有组合,例如以下查询。
;WITH CTE AS
(
SELECT DISTINCT JOBNAME, E.CITYID, SUM(CASE WHEN J.JOBID=E.JOBID THEN 1 ELSE NULL END) M
, AVG(CASE WHEN J.JOBID=E.JOBID AND E.CITYID=E.CITYID THEN SAL ELSE null END) AVG_Sal
FROM EMP E
CROSS JOIN JOB J
GROUP BY JOBNAME, E.CITYID
),
CTE1 AS
(
SELECT DISTINCT JOBNAME, E.CITYID
FROM EMP E
CROSS JOIN JOB J
)
SELECT
case when CITYID is not null and JOBNAME is null then 'Total'
when cityid is null and JOBNAME is null AND [Avg_Sal] IS NOT NULL then 'Grand Total'
else cast(cityid as varchar(100))
end CityId
,JOBNAME
,[Count]
,[Avg_Sal]
from
(
SELECT e.CITYID,j.JOBNAME,SUM(M) [Count], avg([Avg_Sal]) [Avg_Sal]
FROM CTE J
INNER JOIN CTE1 E on E.CITYID=J.CITYID AND J.JOBNAME=E.JOBNAME
GROUP BY ROLLUP (e.CITYID,j.JOBNAME)
) t
输出
+-------------+-------------+-------+---------+
| CityId | JOBNAME | Count | Avg_Sal |
+-------------+-------------+-------+---------+
| 10 | DEVELOPMENT | 2 | 1500 |
+-------------+-------------+-------+---------+
| 10 | HR | 1 | 2000 |
+-------------+-------------+-------+---------+
| 10 | RESEARCH | NULL | NULL |
+-------------+-------------+-------+---------+
| 10 | TESTING | 1 | 1000 |
+-------------+-------------+-------+---------+
| Total | NULL | 4 | 1500 |
+-------------+-------------+-------+---------+
| 20 | DEVELOPMENT | 1 | 2500 |
+-------------+-------------+-------+---------+
| 20 | HR | NULL | NULL |
+-------------+-------------+-------+---------+
| 20 | RESEARCH | NULL | NULL |
+-------------+-------------+-------+---------+
| 20 | TESTING | NULL | NULL |
+-------------+-------------+-------+---------+
| Total | NULL | 1 | 2500 |
+-------------+-------------+-------+---------+
| 30 | DEVELOPMENT | NULL | NULL |
+-------------+-------------+-------+---------+
| 30 | HR | 1 | 1000 |
+-------------+-------------+-------+---------+
| 30 | RESEARCH | NULL | NULL |
+-------------+-------------+-------+---------+
| 30 | TESTING | NULL | NULL |
+-------------+-------------+-------+---------+
| Total | NULL | 1 | 1000 |
+-------------+-------------+-------+---------+
| Grand Total | NULL | 6 | 1600 |
+-------------+-------------+-------+---------+
答案 1 :(得分:1)
要获得所需的结果,您需要首先Impex import job
将所有具有期望的CROSS JOIN
值的作业,然后将CITYID
移到LEFT JOIN
使用EMP
子句来求和并求和,求和并平均薪水:
ROLLUP
输出:
SELECT C.CITYID,
j.JOBNAME,
COUNT(e.CITYID) AS count,
COALESCE(AVG(e.SAL), 0) AS "avg-sal"
FROM JOB J
CROSS JOIN (SELECT DISTINCT CITYID
FROM EMP
WHERE CITYID IN (10, 20)) C
LEFT JOIN EMP e ON e.JOBID = j.JOBID AND e.CITYID = C.CITYID
GROUP BY ROLLUP (C.CITYID, j.JOBNAME)