按 table 2 数据的顺序使用 table 2 从 table 1 检索数据
Retrieving data from table 1 using table 2 in the order of table 2 data
我有两个 tables 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 table),获取每个作业名称的所有 jobid(来自作业 table)并匹配 Emp table,如果存在的话显示计数(Emp table 中存在的 jobid 计数)和 avgsal,否则计数和 avgsal 为 0。
对于 Cityid 的 10 年和 20 年 2015 年状态,输出应该是这样的 '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
我试过连接,但没有正常工作;
使用联接或游标更好吗?
您可以像下面这样使用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 |
+-------------+-------------+-------+---------+
要获得您想要的结果,您需要首先 CROSS JOIN
所有具有所需 CITYID
值的作业,然后您可以 LEFT JOIN
[=15] =] table 并对工作求和并平均薪水,使用 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
我有两个 tables 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 table),获取每个作业名称的所有 jobid(来自作业 table)并匹配 Emp table,如果存在的话显示计数(Emp table 中存在的 jobid 计数)和 avgsal,否则计数和 avgsal 为 0。
对于 Cityid 的 10 年和 20 年 2015 年状态,输出应该是这样的 '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
我试过连接,但没有正常工作; 使用联接或游标更好吗?
您可以像下面这样使用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 |
+-------------+-------------+-------+---------+
要获得您想要的结果,您需要首先 CROSS JOIN
所有具有所需 CITYID
值的作业,然后您可以 LEFT JOIN
[=15] =] table 并对工作求和并平均薪水,使用 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