基于多行的CASE语句

时间:2019-10-25 15:32:24

标签: sql sql-server case

我有一个查询,导致下面的输出(此输出仅用于1 servicelocation_id,但有数千个)。我需要创建一个CASE语句,该语句将查看“实用程序”的多行以确定输出。

如果特定“实用程序”的任何行中都存在NULL“ todate”(例如,Solid Waste),我想创建一个值为“ Active”的“ Status”列。如果特定“实用程序”的所有行都具有“ todate”,则我希望该值是“无效”。

我无法在'fromdate'上执行MAX来确定该实用程序是否处于活动状态,因为带有'todate'的行可能具有比没有该行的行更近的'fromdate'一个。

enter image description here

3 个答案:

答案 0 :(得分:1)

如果您想每servicelocation_id / utility排一行,就希望进行汇总:

select servicelocation_id, utility,
       (case when count(*) = count(to_date)
             then 'Inactive' else 'Active'
        end) as flag
from t
group by servicelocation_id, utility;

如果要保留原始行,可以轻松地将其调整为使用窗口函数而不是聚合。

答案 1 :(得分:0)

您可以在CASE WHEN EXISTS()函数中使用相关子查询来进行EXISTS()

答案 2 :(得分:0)

尝试将您的case语句放在子查询A中,然后使用子查询B从状态为最小值的分组依据中选择A。这样,如果有一个“活动”,则为该值,否则为“非活动”将为该值。

根据要求进行了编辑,以将实用程序包含在分组/联接中

    SELECT YT.servicelocation_id, YT.fromdate, YT.todate, YT.Utility, B.Status
    FROM YourTable YT
    LEFT JOIN 
    (--B subquery
        SELECT servicelocation_id, utility, min(Status) as Status
        FROM (--A subquery
                SELECT servicelocation_id, utility, CASE WHEN todate IS NULL THEN 'Active' ELSE 'Inactive' END as Status
             ) A
        GROUP BY servicelocation_id, utility
    ) B ON YT.servicelocation_id = B.servicelocation_id and YT.utility = B.utility
    --Optional WHERE clause
    WHERE YT.YourField = 'YourCriteria'

根据为servicelocation_id 84061提供的输入,它们都将处于“活动”状态,因为每个实用程序至少具有一个值,而迄今为止为NULL。