如何使用变量或其他技术简化子查询 - MS SQL

时间:2016-10-27 17:43:25

标签: sql sql-server sql-server-2012 subquery case

我还在学习SQL,我花了几个小时寻找我的问题的答案,但无济于事。如果这是一个骗局,请指出我正确的方向!

我正在根据工作流工具生成的数据构建报告。以下是我的结果:

| ID | Name | Company | Contract  |
| 1  | John | Acme    | Freelance |
| 2  | Bill | Acme    | Interne   |
| 3  | Mike | Duff    | Salaried  |

这是主要的实例表" Instance_Table":

| ID | Status | Date       |
| 1  | OK     | 2016-10-21 |
| 2  | Failed | 2016-10-24 |
| 3  | OK     | 2016-10-25 |

这是数据的所在位置" Data_Table":

| DataID | InstanceID | VariableID | Value      |
| 1000   | 1          | 453        | John       |
| 1001   | 1          | 879        | Acme       |
| 1002   | 1          | 1879       | Freelance  |
| 1003   | 1          | 98         | NULL       |
| 1010   | 2          | 453        | Bill       |
| 1011   | 2          | 879        | Acme       |
| 1012   | 2          | 1879       | NULL       |
| 1013   | 2          | 98         | INT        |
| 1020   | 3          | 453        | Mike       |
| 1021   | 3          | 879        | Duff       |
| 1022   | 3          | 1879       | Salaried   |
| 1023   | 3          | 98         | SAL        |

正如您所看到的,合同有两个可能的变量,1879和98.根据实例,只填充一个或两个,98使用短代码而不是完整的单词。

这是我得到结果的痛苦方式:

SELECT IT.ID,

(SELECT DT.value FROM Data_Table DT
 WHERE DT.VariableID = 453 AND IT.ID = DT.InstanceID) as "Name",

(SELECT DT.value FROM Data_Table DT
 WHERE DT.VariableID = 879 AND IT.ID = DT.InstanceID) as "Company",

CASE
 WHEN (SELECT DT.value FROM Data_Table DT
       WHERE DT.VariableID = 1897 AND IT.ID = DT.InstanceID) is NOT NULL
  THEN (SELECT DT.value FROM Data_Table DT
       WHERE DT.VariableID = 1897 AND IT.ID = DT.InstanceID)
  ELSE CASE
        WHEN (SELECT DT.value FROM Data_Table DT
              WHERE DT.VariableID = 98 AND IT.ID = DT.InstanceID) = 'SAL'
         THEN 'Salaried'
        WHEN (SELECT DT.value FROM Data_Table DT
              WHERE DT.VariableID = 98 AND IT.ID = DT.InstanceID) = 'INT'
         THEN 'Intern'
        WHEN (SELECT DT.value FROM Data_Table DT
              WHERE DT.VariableID = 98 AND IT.ID = DT.InstanceID) = 'FRE'
         THEN 'Freelance'
        ELSE '-'
      END
 END as "Contract"

FROM Instance_Table IT

我问如何使用变量或其他方法简化每个子查询的重复,因为我可以想象多次查询同一个表会有巨大的性能损失。

这个例子当然是我实际做的非常简化的版本......我有大约30列要放入我的报告中,数据以各种形式出现,有近70个子查询实例,其中很多重复。该查询运行时间很长,任何帮助它运行得更快的帮助都将非常感激。

3 个答案:

答案 0 :(得分:2)

或许这样的事情?

SELECT IT.id,
       DT_Name.value AS NAME,
       DT_Cmpy.value AS Company,
       [Contract]=CASE
                    WHEN DT_Cont_1.value IS NOT NULL THEN DT_Cont_1.value
                    ELSE
                      CASE DT_Cont_2.value
                        WHEN 'SAL' THEN 'Salaried'
                        WHEN 'INT' THEN 'Intern'
                        WHEN 'FRE' THEN 'Freelance'
                        ELSE '-'
                      END
                  END
FROM   instance_table IT
       LEFT JOIN data_table DT_Name
              ON DT_Name.variableid = 453
                 AND IT.id = DT_Name.instanceid
       LEFT JOIN data_table DT_Cmpy
              ON DT_Cmpy.variableid = 879
                 AND IT.id = DT_Cmpy.instanceid
       LEFT JOIN data_table DT_Cont_1
              ON DT_Cont_1.variableid = 1897
                 AND IT.id = DT_Cont_1.instanceid
       LEFT JOIN data_table DT_Cont_2
              ON DT_Cont_2.variableid = 98
                 AND IT.id = DT_Cont_2.instanceid  

答案 1 :(得分:1)

使用DiffUtil代替相关的子查询

DiffResult.dispatchUpdatesTo

答案 2 :(得分:1)

您可以在没有多次连接到data_table的情况下执行此操作。

SELECT 
    it.ID,
    MAX(CASE WHEN DT.VariableID = 453 THEN DT.VALUE END) AS "Name",
    MAX(CASE WHEN DT.VariableID = 879 THEN DT.VALUE END) AS "Company",
    COALESCE(MAX(CASE WHEN DT.VariableID = 1897 THEN DT.VALUE END), 
        MAX(CASE WHEN DT.VariableID = 98 AND dt.VALUE = 'SAL' THEN 'Salary' 
                 WHEN DT.VariableID = 98 AND dt.VALUE = 'INT' THEN 'Intern'
                 WHEN DT.VariableID = 98 AND dt.VALUE = 'FRE' THEN 'Freelance'
                END)
    ) AS "Contract"
FROM 
    Instance_Table it
    LEFT JOIN Data_Table dt ON  it.ID = dt.InstanceID
GROUP BY it.ID