sql-server - 寻找查询以在数据更改时返回数据值,否则返回空间 ' '

标签 sql-server sql-server-2012

数据库服务器类型 = SQL Server 2012 SP2

这是源表。

  CREATE TABLE a 
  ( 
     e_id INT, 
     r_id INT, 
     d_id INT, 
     s_id INT 
  ); 

CREATE TABLE r 
  ( 
     id   INT, 
     NAME VARCHAR(50) 
  ); 

CREATE TABLE d 
  ( 
     id       INT, 
     calldate DATE 
  ); 

CREATE TABLE e 
  ( 
     id      INT, 
     NAME    VARCHAR(50), 
     initial VARCHAR(5) 
  ); 

CREATE TABLE s 
  ( 
     id        INT, 
     specialty VARCHAR(50) 
  ); 

INSERT INTO a 
VALUES      (8, 
             13, 
             9, 
             13), 
            (8, 
             13, 
             10, 
             13), 
            (8, 
             13, 
             11, 
             13), 
            (8, 
             13, 
             12, 
             13), 
            (8, 
             13, 
             13, 
             13), 
            (8, 
             13, 
             14, 
             13), 
            (10, 
             13, 
             15, 
             13), 
            (10, 
             13, 
             16, 
             13), 
            (10, 
             13, 
             17, 
             13), 
            (16, 
             13, 
             18, 
             13), 
            (16, 
             13, 
             19, 
             13), 
            (16, 
             13, 
             20, 
             13), 
            (9, 
             13, 
             21, 
             13), 
            (9, 
             13, 
             22, 
             13), 
            (9, 
             13, 
             23, 
             13), 
            (9, 
             13, 
             24, 
             13), 
            (16, 
             13, 
             25, 
             13), 
            (16, 
             13, 
             26, 
             13); 
INSERT INTO a 
VALUES
           (10,22,9,13), 
           (10,22,10,13), 
           (10,22,11,13), 
           (10,22,12,13), 
           (10,22,13,13), 
           (16,22,14,13), 
           (16,22,15,13),
           (16,22,16,13),
           (16,22,17,13),
           (9,22,18,13),
           (9,22,19,13),
           (9,22,20,13),
           (18,22,21,13),
           (18,22,22,13),
           (10,22,23,13),
           (10,22,24,13), 
           (9,22,25,13),
           (9,22,26,13);

INSERT INTO r 
VALUES      (13, 
             'Primary'), 
            (22, 
             'Secondary'), 
            (33, 
             'Prim Trd'), 
            (44, 
             'Sec Td'); 

INSERT INTO e 
VALUES      (8, 
             'Jack', 
             'JM'), 
            (9, 
             'Ace', 
             'AQ'), 
            (10, 
             'Mike', 
             'MM'), 
            (16, 
             'George', 
             'GH'),
            (18 ,'Bill',  'BK'  ); 

INSERT INTO s 
VALUES      (13, 
             'Pediatric'), 
            (28, 
             'EMT'), 
            (55, 
             'ER');

INSERT INTO d 
VALUES      (9   , '2015-01-09'),
            (10  , '2015-01-10'),
            (11  , '2015-01-11'),
            (12  , '2015-01-12'),
            (13  , '2015-01-13'),
            (14  , '2015-01-14'),
            (15  , '2015-01-15'),
            (16  , '2015-01-16'),
            (17  , '2015-01-17'),
            (18  , '2015-01-18'),
            (19  , '2015-01-19'),
            (20  , '2015-01-20'),
            (21  , '2015-01-21'),
            (22  , '2015-01-22'),
            (23  , '2015-01-23'),
            (24  , '2015-01-24'),
            (25  , '2015-01-25'),
            (26  , '2015-01-26'),
            (27  , '2015-01-27'),
            (28  , '2015-01-28'),
            (29  , '2015-01-29'),
            (30  , '2015-01-30') 

表 A 是链接表 D、E、R 和 S 的链接表。

表A

║ e_id │ r_id │ d_id │ s_id ║  
╠══════╪══════╪══════╪══════╣  
║ 8    │ 13   │ 9    │ 13   ║  
║ 8    │ 13   │ 10   │ 13   ║  
║ 8    │ 13   │ 11   │ 13   ║  
║ 8    │ 13   │ 12   │ 13   ║  
║ 8    │ 13   │ 13   │ 13   ║  
║ 8    │ 13   │ 14   │ 13   ║  
║ 10   │ 13   │ 15   │ 13   ║  
║ 10   │ 13   │ 16   │ 13   ║   
║ 10   │ 13   │ 17   │ 13   ║  
║ 16   │ 13   │ 18   │ 13   ║  
║ 16   │ 13   │ 19   │ 13   ║   
║ 16   │ 13   │ 20   │ 13   ║  
║ 9    │ 13   │ 21   │ 13   ║  
║ 9    │ 13   │ 22   │ 13   ║  
║ 9    │ 13   │ 23   │ 13   ║  
║ 9    │ 13   │ 24   │ 13   ║  
║ 16   │ 13   │ 25   │ 13   ║  
║ 16   │ 13   │ 26   │ 13   ║  
║ 10   │ 22   │ 9    │ 13   ║  
║ 10   │ 22   │ 10   │ 13   ║  
║ 10   │ 22   │ 11   │ 13   ║  
║ 10   │ 22   │ 12   │ 13   ║  
║ 10   │ 22   │ 13   │ 13   ║  
║ 16   │ 22   │ 14   │ 13   ║  
║ 16   │ 22   │ 15   │ 13   ║  
║ 16   │ 22   │ 16   │ 13   ║   
║ 16   │ 22   │ 17   │ 13   ║  
║ 9    │ 22   │ 18   │ 13   ║  
║ 9    │ 22   │ 19   │ 13   ║   
║ 9    │ 22   │ 20   │ 13   ║  
║ 18   │ 22   │ 21   │ 13   ║  
║ 18   │ 22   │ 22   │ 13   ║  
║ 10   │ 22   │ 23   │ 13   ║  
║ 10   │ 22   │ 24   │ 13   ║  
║ 9    │ 22   │ 25   │ 13   ║  
║ 9    │ 22   │ 26   │ 13   ║     

表D

║ id │ calldate   ║  
╠════╪════════════╣  
║ 9  │ 2015-01-09 ║  
║ 10 │ 2015-01-10 ║  
║ 11 │ 2015-01-11 ║  
║ 12 │ 2015-01-12 ║  
║ 13 │ 2015-01-13 ║  
║ 14 │ 2015-01-14 ║  
║ 15 │ 2015-01-15 ║  
║ 16 │ 2015-01-16 ║  
║ 17 │ 2015-01-17 ║  
║ 18 │ 2015-01-18 ║  
║ 19 │ 2015-01-19 ║  
║ 20 │ 2015-01-20 ║  
║ 21 │ 2015-01-21 ║  
║ 22 │ 2015-01-22 ║  
║ 23 │ 2015-01-23 ║  
║ 24 │ 2015-01-24 ║  
║ 25 │ 2015-01-25 ║  
║ 26 │ 2015-01-26 ║  
║ 27 │ 2015-01-27 ║  
║ 28 │ 2015-01-28 ║  
║ 29 │ 2015-01-29 ║  
║ 30 │ 2015-01-30 ║  

表E

╔════╤════════╤═════════╗  
║ id │ name   │ initial ║  
╠════╪════════╪═════════╣  
║ 8  │ Jack   │ JM      ║  
║ 9  │ Ace    │ AQ      ║  
║ 10 │ Mike   │ MM      ║  
║ 16 │ George │ GH      ║  
║ 18 │ Bill   │ BK      ║  
╚════╧════════╧═════════╝  

表R

╔════╤═══════════╗  
║ id │ name      ║  
╠════╪═══════════╣  
║ 13 │ Primary   ║  
║ 22 │ Secondary ║  
║ 33 │ Prim Trd  ║  
║ 44 │ Sec Td    ║  
╚════╧═══════════╝  

表S

|ID | Specialty |  
|---+-----------|  
|13 | Pediatric |  
|28 | EMT       |  
|55 | ER        |  

这是我认为可行但会产生错误的查询:

SELECT d.calldate, 
       Max(CASE 
             WHEN s.id = 13 
                  AND r.NAME = 'Primary' THEN ( e.NAME ) 
           END) AS [Primary], 
       Max(CASE 
             WHEN s.id = 13 
                  AND r.NAME = 'Secondary' THEN ( e.NAME ) 
           END) AS [Secondary], 
       Max(CASE 
             WHEN s.id = 13 
                  AND r.NAME = 'Primary' 
                  AND ( ( e.id = (SELECT e1.id 
                                  FROM   a a1 
                                         INNER JOIN e e1 
                                                 ON e1.id = a1.e_id 
                                         INNER JOIN d d1 
                                                 ON d1.id = a1.d_id 
                                         INNER JOIN s s1 
                                                 ON s1.id = a1.s_id 
                                         INNER JOIN r r1 
                                                 ON r1.id = a1.r_id 
                                  WHERE  d1.calldate = CONVERT(DATE, 
                                                       Dateadd(dd, -1, 
                                                       d.calldate), 
                                                       101) 
                                         AND r1.NAME = 'Primary' 
                                         AND s1.id = 13) ) 
                        AND ( e.id = (SELECT e1.id 
                                      FROM   a a1 
                                             INNER JOIN e e1 
                                                     ON e1.id = a1.e_id 
                                             INNER JOIN d d1 
                                                     ON d1.id = a1.d_id 
                                             INNER JOIN s s1 
                                                     ON s1.id = a1.s_id 
                                             INNER JOIN r r1 
                                                     ON r1.id = a1.r_id 
                                      WHERE  d1.calldate = CONVERT(DATE, Dateadd 
                                                           (dd, 1, 
d.calldate), 
101 
) 
AND r1.NAME = 'Primary' 
AND s1.id = 13) ) ) THEN ' ' 
ELSE e.initial 
END) AS [PrimaryINIT], 
Max(CASE 
WHEN s.id = 13 
AND r.NAME = 'Secondary' 
AND ( e.id = (SELECT e1.id 
FROM   a a1 
INNER JOIN e e1 
ON e1.id = a1.e_id 
INNER JOIN d d1 
ON d1.id = a1.d_id 
INNER JOIN s s1 
ON s1.id = a1.s_id 
INNER JOIN r r1 
ON r1.id = a1.r_id 
WHERE  d1.calldate = CONVERT(DATE, Dateadd(dd, -1, 
d.calldate), 
101) 
AND r1.NAME = 'Secondary' 
AND s1.id = 13) 
AND ( e.id = (SELECT e1.id 
FROM   a a1 
INNER JOIN e e1 
ON e1.id = a1.e_id 
INNER JOIN d d1 
ON d1.id = a1.d_id 
INNER JOIN s s1 
ON s1.id = a1.s_id 
INNER JOIN r r1 
ON r1.id = a1.r_id 
WHERE  d1.calldate = CONVERT(DATE, Dateadd(dd, 1, 
d.calldate), 
101 
) 
AND r1.NAME = 'Secondary' 
AND s1.id = 13) ) ) THEN ' ' 
ELSE e.initial 
END) AS [SecondaryINIT] 
FROM   a 
       INNER JOIN e 
               ON e.id = a.e_id 
       INNER JOIN d 
               ON d.id = a.d_id 
       INNER JOIN s 
               ON s.id = a.s_id 
       INNER JOIN r 
               ON r.id = a.r_id 
WHERE  Datepart(mm, d.calldate) = 1 
       AND Datepart(year, d.calldate) = 2015 
GROUP  BY d.calldate 

这是我们从查询中寻找的结果。

(请注意,初始列仅在数据更改前后返回列值):

查询的所需结果。

╔════════════╤═════════╤═══════════╤═════════╤═══════════╗  
║ callDate   │ Primary │ Secondary │ PrimINIT│ SeconINIT ║  
╠════════════╪═════════╪═══════════╪═════════╪═══════════╣  
║ 2015-01-09 │ Jack    │ Mike      │ JM      │ MM        ║  
║ 2015-01-10 │ Jack    │ Mike      │         │           ║  
║ 2015-01-11 │ Jack    │ Mike      │         │           ║  
║ 2015-01-12 │ Jack    │ Mike      │         │           ║  
║ 2015-01-13 │ Jack    │ Mike      │         │ MM        ║  
║ 2015-01-14 │ Jack    │ George    │ JM      │ GH        ║  
║ 2015-01-15 │ Mike    │ George    │ MM      │           ║  
║ 2015-01-16 │ Mike    │ George    │         │           ║  
║ 2015-01-17 │ Mike    │ George    │ MM      │ GH        ║  
║ 2015-01-18 │ George  │ Ace       │ GH      │ AQ        ║  
║ 2015-01-19 │ George  │ Ace       │         │           ║  
║ 2015-01-20 │ George  │ Ace       │ GH      │ AQ        ║  
║ 2015-01-21 │ Ace     │ Bill      │ AQ      │ BK        ║  
║ 2015-01-22 │ Ace     │ Bill      │         │ BK        ║  
║ 2015-01-23 │ Ace     │ Mike      │         │ MM        ║  
║ 2015-01-24 │ Ace     │ Mike      │ AQ      │ MM        ║  
║ 2015-01-25 │ George  │ Ace       │ GH      │ AQ        ║  
║ 2015-01-26 │ George  │ Ace       │ GH      │ AQ        ║  
╚════════════╧═════════╧═══════════╧═════════╧═══════════╝  

最佳答案

像这样尝试:

WITH Pivoted AS
(
    SELECT d.calldate AS calldate
          ,MAX(CASE WHEN r.Name='Primary' THEN e.NAME END) AS [Primary]
          ,MAX(CASE WHEN r.Name='Secondary' THEN e.NAME END) AS [Secondary]
          ,MAX(CASE WHEN r.Name='Primary' THEN e.initial END) AS [PrimINIT]
          ,MAX(CASE WHEN r.Name='Secondary' THEN e.initial END) AS [SeconINIT]
    FROM a
    INNER JOIN e ON a.e_id=e.id
    INNER JOIN r ON a.r_id=r.id
    INNER JOIN d ON a.d_id=d.id
    INNER JOIN s ON a.s_id=s.id
    GROUP BY d.calldate
)
,WithNeighbours AS
(
    SELECT *
          ,ISNULL(LAG([Primary]) OVER(ORDER BY calldate,[Primary]),'') AS PrevPrim 
          ,ISNULL(LAG([Secondary]) OVER(ORDER BY calldate,[Secondary]),'') AS PrevSecon
          ,ISNULL(LEAD([Primary]) OVER(ORDER BY calldate,[Primary]),'') AS NxtPrim 
          ,ISNULL(LEAD([Secondary]) OVER(ORDER BY calldate,[Secondary]),'') AS NxtSecon
    FROM Pivoted
)
SELECT calldate 
      ,[Primary]
      ,[Secondary]
      ,CASE WHEN [Primary]<>PrevPrim OR [Primary]<>NxtPrim THEN PrimINIT ELSE '' END AS PrimINIT
      ,CASE WHEN [Secondary]<>PrevSecon OR [Secondary]<>NxtSecon THEN SeconINIT ELSE '' END AS SeconINIT
FROM WithNeighbours
ORDER BY calldate

给定数据的结果

+------------+---------+-----------+----------+-----------+
| calldate   | Primary | Secondary | PrimINIT | SeconINIT |
+------------+---------+-----------+----------+-----------+
| 2015-01-09 | Jack    | Mike      | JM       | MM        |
+------------+---------+-----------+----------+-----------+
| 2015-01-10 | Jack    | Mike      |          |           |
+------------+---------+-----------+----------+-----------+
| 2015-01-11 | Jack    | Mike      |          |           |
+------------+---------+-----------+----------+-----------+
| 2015-01-12 | Jack    | Mike      |          |           |
+------------+---------+-----------+----------+-----------+
| 2015-01-13 | Jack    | Mike      |          | MM        |
+------------+---------+-----------+----------+-----------+
| 2015-01-14 | Jack    | George    | JM       | GH        |
+------------+---------+-----------+----------+-----------+
| 2015-01-15 | Mike    | George    | MM       |           |
+------------+---------+-----------+----------+-----------+
| 2015-01-16 | Mike    | George    |          |           |
+------------+---------+-----------+----------+-----------+
| 2015-01-17 | Mike    | George    | MM       | GH        |
+------------+---------+-----------+----------+-----------+
| 2015-01-18 | George  | Ace       | GH       | AQ        |
+------------+---------+-----------+----------+-----------+
| 2015-01-19 | George  | Ace       |          |           |
+------------+---------+-----------+----------+-----------+
| 2015-01-20 | George  | Ace       | GH       | AQ        |
+------------+---------+-----------+----------+-----------+
| 2015-01-21 | Ace     | Bill      | AQ       | BK        |
+------------+---------+-----------+----------+-----------+
| 2015-01-22 | Ace     | Bill      |          | BK        |
+------------+---------+-----------+----------+-----------+
| 2015-01-23 | Ace     | Mike      |          | MM        |
+------------+---------+-----------+----------+-----------+
| 2015-01-24 | Ace     | Mike      | AQ       | MM        |
+------------+---------+-----------+----------+-----------+
| 2015-01-25 | George  | Ace       | GH       | AQ        |
+------------+---------+-----------+----------+-----------+
| 2015-01-26 | George  | Ace       | GH       | AQ        |
+------------+---------+-----------+----------+-----------+

关于sql-server - 寻找查询以在数据更改时返回数据值,否则返回空间 ' ',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38211905/

相关文章:

sql-server - SQL Server 中的 Row_Number()

sql - 如何编写 select inside case 语句

SSIS: "Incorrect syntax near ' GO'。”错误

javascript - 页面加载后 Gridview 卡住 Pane 标题未卡住

sql - 创建与列值出现相关的计算列

sql-server - 我们如何在使用sql server获取记录数时减少临时表扫描的成本

sql-server - 有没有办法在 SSMS 中扩展 SELECT * from #Temp_Table 中的列列表?

sql - 在 SQL Server 中将数据类型 Varchar 更改为 Varbinary(max)

sql-server - 用于存储文件的数据库设计决策

sql-server - INNER/RIGHT/LEFT JOIN 怎么会比 FULL JOIN 慢 14 倍?