我有两个表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')
;
我想显示所有的工作名数和平均工资;对于jobname,如果jobid不存在则显示0
对于给定的输入cityid,YEAR和STATUS(Emp表),取每个作业名的所有jobid(来自作业表)并在Emp表中匹配,如果存在显示计数(Emp表中存在的作业数)和其他0作为计数和avgsal。
对于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
我尝试通过加入,但没有正常工作;是否更好地使用连接或光标?
为了得到你想要的结果,你需要首先CROSS JOIN
所有所需的CITYID
值的工作,然后你可以LEFT JOIN
到EMP
表和SUM工作和平均工资,使用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)
输出:
CITYID JOBNAME count avg-sal
10 DEVELOPMENT 2 1500
10 HR 1 2000
10 RESEARCH 0 0
10 TESTING 1 1000
10 4 1500
20 DEVELOPMENT 1 2500
20 HR 0 0
20 RESEARCH 0 0
20 TESTING 0 0
20 1 2500
5 1700
你可以像下面这样使用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 |
+-------------+-------------+-------+---------+