【问题标题】:What are options for a nested case-type structure in a table join in TSQL?SQL 中表连接中嵌套案例类型结构的选项有哪些?
【发布时间】:2019-04-11 02:52:30
【问题描述】:

我需要在两个条件下加入 - 第一个很简单,但第二个似乎要求嵌套 case 语句,但我无法弄清楚如何使其工作或更好的选择。

问题是我的活动每天可能发生一次或两次。如果它每天发生一次,我可以在日期加入。如果它每天发生两次,我需要根据是早上还是下午适当地从表 X 加入表 Y,这样做我需要基本上从早上和下午将一堆时间四舍五入到每个的单个值加入。

这很好用:

Inner join table x on x.ser = y.ser and (case when X <= 12 then 9 else 
15) = (case when Y <= 12 then 9 else 15)

但是,如果我在原始语句周围添加另一个 case 语句,它就会分崩离析,而且看起来像是垃圾代码,所以我认为必须有更好的方法来解决这个问题,但它让我无法理解。

case when (code = BID) then 
(case when X <= 12 then 9 else 15) = (case when Y <= 12 then 9 else 15)
else X = Y

实际的非工作代码如下。

    INNER JOIN dbo.Image img on img.Ser = sa.Ser and 
        case when (ac.ActivityCode = 'BID') then    
            CASE WHEN DATEPART(hour, img.CreationDate) <= 12 THEN 
                 DATEADD(hh, 9, DATEADD(dd, DATEDIFF(dd, 0, 
                 img.CreationDate), 0)) ELSE DATEADD(hh, 15, DATEADD(dd, 
                 DATEDIFF(dd, 0, img.CreationDate), 0))  
            END = CASE WHEN DATEPART(hour, sa.ActualStartDate) <= 12 THEN 
                       DATEADD(hh, 9, DATEADD(dd, DATEDIFF(dd, 0, 
                        sa.ActualStartDate), 0)) ELSE DATEADD(hh, 15, 
                        DATEADD(dd, DATEDIFF(dd, 0, sa.ActualStartDate), 
                        0)) 
                    END 
          ELSE  sa.ActualStartDate = img.CreationDate
        END

【问题讨论】:

  • 您是否尝试将查询分为 2 个查询(一个用于单个活动,另一个用于多个活动)?如果不是,请先尝试将它们分开,为两个查询获得正确的结果,然后检查它们并尽可能多地调整它们,然后看看如何将它们合并到一个查询中。
  • 您的建议正是我最终要去的地方。正如你所建议的那样,我认为这样更容易到达我想去的地方。另一件事也出现了——用户告诉我,我的方法在 99% 的时间里都会产生正确的答案,但是在极少数边缘情况下它不起作用,因此你建议的方式将是无论如何都需要。
  • 如果分开,您可以更轻松快捷地涵盖所有可能的情况,但有时需要为每种情况使用单独的查询。因此,它并不总是一个查询解决方案。

标签: sql-server tsql join nested


【解决方案1】:

CASE 语句中不能有比较语句 {expression 1} = {expression 2}

应该是这样的

INNER JOIN dbo.Image img  on  img.Ser = sa.Ser 
                         and  CASE ... END = CASE ... END

但是您的查询将难以阅读。为什么不使用CTE。并计算CTE中的新表达式

; WITH
CTE1 AS 
( 
    Col2 = CASE WHEN DATEPART(hour, img.CreationDate) <= 12 .....
),
CTE2 AS 
( 
    Col2 = CASE WHEN DATEPART(hour, sa.ActualStartDate) <= 12 .....
)
SELECT *
FROM   CTE1 c1 
JOIN   CTE2 c2  ON c1.Ser  = c2.Ser
               AND c2.Col2 = c2.Col2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-23
    • 1970-01-01
    • 2023-03-17
    • 2013-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-13
    相关资源
    最近更新 更多