【问题标题】:Use Derived/Temporary column in Where Clause [duplicate]在 Where 子句中使用派生/临时列 [重复]
【发布时间】:2019-02-19 12:32:46
【问题描述】:

这是我的查询。问题是我试图将派生的“LineNo”字段应用为 where 子句。下面的查询不起作用。简而言之,如果 LineHrs 列的值 > 0,它将将此派生列设置为给定值(例如,如果 Line5Hrs = 1.4,则行的“LineNo”=“第 5 行”)。我想使用这个值来搜索特定行的所有工作。

SELECT      tblA.PROJECT_ID, 
            tblB.Line1Hrs, 
            tblB.Line2Hrs, 
            tblB.Line3Hrs, 
            tblB.Line4Hrs,
            tblB.Line5Hrs,
            tblB.Line6Hrs, 
            tblB.Line7Hrs, 
            "LineNo" =
                        CASE 
                            WHen tblB.Line1Hrs > 0 Then 'Line1'
                            WHen tblB.Line2Hrs > 0 Then 'Line2'
                            WHen tblB.Line3Hrs > 0 Then 'Line3'
                            WHen tblB.Line4Hrs > 0 Then 'Line4'
                            WHen tblB.Line5Hrs > 0 Then 'Line5'
                            WHen tblB.Line6Hrs > 0 Then 'Line6'
                            WHen tblB.Line7Hrs > 0 Then 'Line7'
                        End
FROM            tblA INNER JOIN tblB
                ON tblA.blah = tblB.blah AND
                tblA.blab = tblB.blab

WHERE         LineNo = 'Line5'

【问题讨论】:

    标签: sql sql-server tsql derived-column


    【解决方案1】:

    您不能在 where 子句中使用派生/别名列名。尝试将查询封装为子查询,然后将 where 放在主查询上。

    select * from (
        SELECT      tblA.PROJECT_ID, 
                    tblB.Line1Hrs, 
                    tblB.Line2Hrs, 
                    tblB.Line3Hrs, 
                    tblB.Line4Hrs,
                    tblB.Line5Hrs,
                    tblB.Line6Hrs, 
                    tblB.Line7Hrs, 
                    "LineNo" =
                                CASE 
                                    WHen tblB.Line1Hrs > 0 Then 'Line1'
                                    WHen tblB.Line2Hrs > 0 Then 'Line2'
                                    WHen tblB.Line3Hrs > 0 Then 'Line3'
                                    WHen tblB.Line4Hrs > 0 Then 'Line4'
                                    WHen tblB.Line5Hrs > 0 Then 'Line5'
                                    WHen tblB.Line6Hrs > 0 Then 'Line6'
                                    WHen tblB.Line7Hrs > 0 Then 'Line7'
                                End
        FROM            tblA 
        INNER JOIN tblB
            ON tblA.blah = tblB.blah AND
               tblA.blab = tblB.blab
    )
    WHERE   LineNo = 'Line5'
    

    【讨论】:

      【解决方案2】:

      使用 CTE 或子查询。例如:

      WITH CTE AS
          (SELECT tblA.PROJECT_ID,
                  tblB.Line1Hrs,
                  tblB.Line2Hrs,
                  tblB.Line3Hrs,
                  tblB.Line4Hrs,
                  tblB.Line5Hrs,
                  tblB.Line6Hrs,
                  tblB.Line7Hrs,
                  CASE
                       WHEN tblB.Line1Hrs > 0 THEN 'Line1'
                       WHEN tblB.Line2Hrs > 0 THEN 'Line2'
                       WHEN tblB.Line3Hrs > 0 THEN 'Line3'
                       WHEN tblB.Line4Hrs > 0 THEN 'Line4'
                       WHEN tblB.Line5Hrs > 0 THEN 'Line5'
                       WHEN tblB.Line6Hrs > 0 THEN 'Line6'
                       WHEN tblB.Line7Hrs > 0 THEN 'Line7'
                  END AS [LineNo]
           FROM tblA
                INNER JOIN tblB ON tblA.blah = tblB.blah
                               AND tblA.blab = tblB.blab)
      SELECT PROJECT_ID,
             Line1Hrs,
             Line2Hrs,
             Line3Hrs,
             Line4Hrs,
             Line5Hrs,
             Line6Hrs,
             Line7Hrs,
             [LineNo]
      FROM CTE
      WHERE [LineNo] = 'Line5';
      

      您不能在WHERE 子句中的SELECT 中引用列(通过别名),因为WHERESELECT 之前被评估:Logical Processing Order of the SELECT statement

      【讨论】:

        【解决方案3】:

        我喜欢为此目的使用apply

        SELECT . . ., v.lineno
        FROM tblA a INNER JOIN
             tblB b
             ON a.blah = b.blah AND
                a.blab = b.blab CROSS APPLY
             (VALUES (CASE WHEN b.Line1Hrs > 0 Then 'Line1'
                           WHEN b.Line2Hrs > 0 Then 'Line2'
                           WHEN b.Line3Hrs > 0 Then 'Line3'
                           WHEN b.Line4Hrs > 0 Then 'Line4'
                           WHEN b.Line5Hrs > 0 Then 'Line5'
                           WHEN b.Line6Hrs > 0 Then 'Line6'
                           WHEN b.Line7Hrs > 0 Then 'Line7'
                      END)
             ) v(LineNo)
        WHERE v.LineNo = 'Line5'
        

        【讨论】:

          【解决方案4】:

          我会使用APPLY,因为您不能将derived/alias 列名与WHERE 子句一起使用:

          SELECT . . . 
          FROM tblA INNER JOIN 
               tblB
               ON tblA.blah = tblB.blah AND 
                  tblA.blab = tblB.blab  CROSS APPLY
               ( VALUES (CASE WHen tblB.Line1Hrs > 0 Then 'Line1'
                              WHen tblB.Line2Hrs > 0 Then 'Line2'
                              WHen tblB.Line3Hrs > 0 Then 'Line3'
                              WHen tblB.Line4Hrs > 0 Then 'Line4'
                              WHen tblB.Line5Hrs > 0 Then 'Line5'
                              WHen tblB.Line6Hrs > 0 Then 'Line6'
                              WHen tblB.Line7Hrs > 0 Then 'Line7'
                         End)  
              ) BB (LineNo )
          Where BB.LineNo = 'Line5';
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-10-12
            • 1970-01-01
            • 1970-01-01
            • 2010-11-14
            • 2010-12-25
            • 1970-01-01
            • 2021-11-04
            • 2016-11-30
            相关资源
            最近更新 更多