【问题标题】:Create a new column in a sql query using case statement使用 case 语句在 sql 查询中创建新列
【发布时间】:2018-12-19 18:09:10
【问题描述】:

我已经完成了一些表连接,下面是我的数据的外观。

Cust_No Account_No  Product_H_f Product_H_L
123     A9023         Core      Training
123     A9023         Core      Training
834     A9023         Core      Complimentary
634     A9024         Core      Complimentary
264     A9025         DTB       Training
263     A9025         DTB       Complimentary
677     A9025         DTB       Training

我想在这个结果中添加一个名为“有培训的客户_没有”的列,应该如下所示。 (我的原始查询非常复杂,使用左连接在 6 个表上进行连接)

Cust_No Account_No  Product_H_f Product_H_L Cust_has_Training
123    A9023        Core        Training        Yes
123    A9023        Core        Training        Yes
834    A9023        Core        Complimentary   Yes 
834    A9023        Core        Training        Yes
634    A9024        Core        Complimentary   No
264    A9025        DTB         Training        Yes
263    A9025        DTB         Complimentary   No
677    A9025        DTB         Training        Yes
677    A9025        DTB         Basic           Yes

我正在使用下面的代码来实现这一点,它似乎正在工作。但由于我有 4800 万条记录,运行它需要很长时间。有没有办法优化这个查询?

SELECT Cust_No, 
       Account_No,  
       Product_H_f, 
       Product_H_L,
(CASE WHEN Cust_No IN (SELECT distinct(Cust_No) from table where 
Product_H_L='Training') then 'Yes' else 'No' end) as 'Cust_has_Training'
FROM TABLE 

【问题讨论】:

  • 使用 EXISTS 几乎肯定会获得更好的性能,但性能可能与连接到视图或执行 SELECT 中的查询的子查询一样好
  • 我确实尝试过使用 EXISTS,但不知何故它给出了不正确的结果。它肯定跑得更快。

标签: sql sql-server case


【解决方案1】:

如果您有一个复杂的查询,添加这个新计算的最有效(也是最简单)的方法可能是基于 Windowed Aggregates

SELECT Cust_No, 
       Account_No,  
       Product_H_f, 
       Product_H_L,
       -- returns YES when any row for a customer has 'Training'
       MAX(CASE WHEN Product_H_L='Training' THEN 'Yes' else 'No' end)
       OVER (PARTITION BY Cust_No) as 'Cust_has_Training'
FROM TABLE 

【讨论】:

    【解决方案2】:

    EXISTS 可以很好地用于此目的,子查询连接也可以。如果不提供更多信息,您可能不会比通用的“这通常更快”更好。

    SELECT Cust_No, 
           Account_No,  
           Product_H_f, 
           Product_H_L,
    (CASE WHEN Cust_has_Training.[Cust_No] is not null then 'Yes' else 'No' end) as 'Cust_has_Training'
    FROM TABLE 
    LEFT JOIN (
       SELECT distinct(Cust_No) AS [Cust_No]
       from table where 
       Product_H_L='Training'
    ) Cust_has_Training ON Cust_has_Training.[Cust_No]=Table.[Cust_No]
    

    【讨论】:

    • @Mili 。 . .我希望窗口函数或exists 表现更好。你能详细说明你为什么接受这个答案吗?
    【解决方案3】:

    EXISTS()怎么样

    SELECT Cust_No, 
           Account_No,  
           Product_H_f, 
           Product_H_L,
    (CASE WHEN EXISTS(SELECT 1 FROM TABLE WHERE Cust_No = T1.Cust_No AND
    Product_H_L='Training') then 'Yes' else 'No' end) as 'Cust_has_Training'
    FROM TABLE T1
    

    【讨论】:

      猜你喜欢
      • 2017-04-21
      • 1970-01-01
      • 2019-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-23
      • 2014-12-05
      相关资源
      最近更新 更多