按表2数据的顺序使用表2从表1检索数据

时间:2019-02-24 05:10:53

标签: sql sql-server matching

我有两个表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更好吗?

2 个答案:

答案 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 

Online Demo

编辑:对于所有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

Demo 2

输出

+-------------+-------------+-------+---------+
| 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)

Demo on dbfiddle