简体   繁体   English

SQL Server:匹配两个表并按正确列的顺序结果

[英]SQL Server: matching two tables and results in the order of proper column

I have two tables JOB and EMP ;我有两个表JOBEMP structure and values are like this:结构和值是这样的:

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, 'A'),
       (400, 3, 1000, 10, 2016, 'A'),
       (500, 6, 3000, 10, 2015, 'E'),
       (600, 8, 1000, 30, 2015, 'A'),
       (700, 8, 2000, 10, 2015, 'E'),
       (800, 9, 1500, 10, 2015, 'A');

I want to display all jobname count and avg salaries;我想显示所有工作名称计数和平均工资; for the jobname if jobid's not exists then display 0对于作业名称,如果作业 ID 不存在,则显示 0

For the given input cityid , YEAR and STATUS ( Emp table), take all jobid for each jobname (from job table ) and match in Emp table, if exists display count (count of jobid present in Emp table) and avgsal else 0 for count and avgsal .对于给定的输入cityidYEARSTATUSEmp表),采取所有jobid为每个jobname (从job表)和匹配Emp表,如果存在显示count (计数的jobid存在于Emp表)和avgsal else 0countavgsal And Sal is calculated based on Status . Sal是根据Status计算的。 If Status is 'A' Sal goes to Status-A-Sal else Status-E-Sal .如果Status是 'A' Sal 转到Status-A-Sal else Status-E-Sal And for each matched ie non zero record put 'X' in another field对于每个匹配的非零记录,将“X”放在另一个字段中

Output should be like this for Cityid 's 10 and 20 year 2015. Results should be displayed first for Status 'A' and then Status 'E'.对于Cityid 2015 年的第 10 年和第 20 年,输出应如下所示。应首先显示Status “A”的结果,然后显示Status “E”。 Added status type field in result .在 result 中添加了状态类型字段。

Cityid  Status-type jobname         count   STATUS      sal
--------------------------------------------------------------
10      STATUSA     development     2       X           1500
10      STATUSA     TESTING         0                   0
10      STATUSA     RESEARCH        1       X           1500 
10      STATUSA     HR              0                   0
10      total                       3                   0
10      STATUSE     development     0                   0
10      STATUSE     TESTING         0                   0
10      STATUSE     RESEARCH        0                   0 
10      STATUSE     HR              1        X          2000
10      total                       1                   2000

20      STATUSA     development     1        X          2500
20      STATUSA     TESTING         0                   0
20      STATUSA     RESEARCH        0                   0 
20      STATUSA     HR              0                   0
20      total                       1                   2500
20      STATUSE     development     0                   0
20      STATUSE     TESTING         0                   0
20      STATUSE     RESEARCH        0                   0 
20      STATUSE     HR              0                   0
20      total                       0                   0

How to bring the results one status after another ?如何带来一个又一个的结果?

I've tried like this but its throwing我试过这样但它投掷

SELECT C.CITYID  AS CITYID,
           CASE WHEN P.STATUS ='A' THEN 'STATUSA' ELSE 'STATUSE' END AS STATUS_TYPE ,
           COALESCE(J.JOBNAME, 'TOTAL') AS JOBNAME,
           COUNT(CASE WHEN P.STATUS ='A' THEN P.CITYID END ) AS COUNT ,
           COALESCE(AVG(CAST(CASE WHEN P.STATUS = 'A' THEN P.SAL END AS DECIMAL(13,2)))/12 , 0) AS "AVG SAL",
           COUNT(CASE WHEN P.STATUS ='E' THEN P.CITYID END ) AS  COUNT  ,
           COALESCE(AVG(CAST(CASE WHEN P.STATUS = 'E' THEN P.SAL END AS DECIMAL(13,2)))/12 , 0) AS "AVG SAL"
    FROM JOB1 J
    CROSS JOIN 
            (SELECT DISTINCT CITYID 
                FROM EMP1  B WHERE CITYID = 10

            ) C
    LEFT JOIN EMP1 P ON P.JOBID = J.JOBID 
            AND  P.CITYID = C.CITYID and
            YEAR = 2015
        GROUP BY ROLLUP(C.CITYID,  J.JOBNAME );

ERROR: Column 'EMP1.STATUS' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.错误:列“EMP1.STATUS”在选择列表中无效,因为它不包含在聚合函数或 GROUP BY 子句中。

IF OBJECT_ID('tempdb..#JOB') IS NOT NULL
    DROP TABLE #JOB

CREATE TABLE #JOB 
(
    JOBID SMALLINT UNIQUE NOT NULL,
    JOBNAME CHAR(15)
);

IF OBJECT_ID('tempdb..#EMP') IS NOT NULL
    DROP TABLE #EMP

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, 'A'),
       (400, 3, 1000, 10, 2016, 'A'),
       (500, 6, 3000, 10, 2015, 'E'),
       (600, 8, 1000, 30, 2015, 'A'),
       (700, 8, 2000, 10, 2015, 'E'),
       (800, 9, 1500, 10, 2015, 'A');

;with cteJobDict as (
    select
            distinct
            j.JOBNAME
    from
            #JOB j
)
,cteStatusDict as(
    select
            distinct STATUS
    from
            #EMP e
),cteCityDict as (
    select
            distinct CITYID
    from
            #EMP
)
,cteJobStatusCityMatrix as(
    select
            *
    from
            cteJobDict
    cross apply cteStatusDict
    cross apply cteCityDict
)
,cteEmpWithJobName as (
    select
            e.*
            ,j.JOBNAME
    from
            #EMP e
    join    #JOB j on j.JOBID=e.JOBID
), cteData as (
SELECT
        m.CITYID
        ,CASE WHEN m.STATUS ='A' THEN 'STATUSA' ELSE 'STATUSE' end as [Status-type]
        ,CASE WHEN m.STATUS ='A' THEN 1 ELSE 3 end as [Status-order]
        ,m.JOBNAME
        ,count(distinct e.EMPID) count
        ,iif(count(distinct e.EMPID)>0,'X','') status
        ,isnull(avg(e.sal),0) sal
FROM
        cteJobStatusCityMatrix m
left join cteEmpWithJobName e on e.CITYID=m.CITYID and e.STATUS=m.STATUS and e.JOBNAME=m.JOBNAME and e.YEAR=2015
where
        m.CITYID in (10,20)
group by
        m.CITYID
        ,m.STATUS
        ,m.JOBNAME
union
SELECT
        m.CITYID
        ,'total' as [Status-type]
        ,CASE WHEN m.STATUS ='A' THEN 2 ELSE 4 end as [Status-order]
        ,null
        ,count(distinct e.EMPID) count
        ,iif(count(distinct e.EMPID)>0,'X','') status
        ,isnull(avg(e.sal),0) sal
FROM
        cteJobStatusCityMatrix m
left join cteEmpWithJobName e
            on e.CITYID=m.CITYID
            and e.STATUS=m.STATUS
            and e.JOBNAME=m.JOBNAME
            and e.YEAR=2015 -- here goes year
where
        m.CITYID in (10,20) -- here goes cityid
group by
        m.CITYID
        ,m.STATUS)
select
        CITYID
        ,[Status-type]
        ,JOBNAME
        ,count
        ,status
        ,sal
from
        cteData
order by
        CITYID
        ,[Status-order]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM