是否可以在WHERE子句中使用临时列

时间:2014-12-04 04:36:41

标签: sql sql-server tsql where-clause

  1. 我只想显示RequestStatus_hodIN PROCESS
  2. 的数据
  3. 但查询似乎通过忽略where子句
  4. 来显示所有数据
  5. 正如您所看到的,我已尝试重复WHERE RequestStatus_hod = 'IN PROCESS',但它只显示为NULL
  6. 我已尝试使用临时列RequestStatus_hods并已收到an invalid column error
  7. SQL语句:

    SELECT DISTINCT 
       A.RequestNumber, A.EmployeeId,
       STUFF((SELECT ', ' + CAST(B.RequestDetailsId AS VARCHAR(255))
              FROM [dbo].[REQUISITION] C 
              JOIN [dbo].[REQUISITION_DETAILS] B ON C.RequestDetailsId = B.RequestDetailsId
              WHERE C.RequestNumber = A.RequestNumber AND C.EmployeeId = A.EmployeeId -- AND RequestStatus_hod = 'IN PROCESS'
              FOR XML PATH ('')), 1, 2, '') AS RequestDetailIds,
       STUFF((SELECT ', ' + CAST(B.StockId AS VARCHAR(255))
              FROM [dbo].[REQUISITION] C 
              JOIN [dbo].[REQUISITION_DETAILS] B ON C.RequestDetailsId = B.RequestDetailsId 
              JOIN [dbo].[STOCK] F ON F.StockId = B.StockId
              WHERE C.RequestNumber = A.RequestNumber AND C.EmployeeId = A.EmployeeId -- AND RequestStatus_hod = 'IN PROCESS'
              FOR XML PATH ('')), 1, 2, '') AS StockIds,
       STUFF((SELECT ', ' + CAST(B.RequestQuantity AS VARCHAR(255))
              FROM [dbo].[REQUISITION] C 
              JOIN [dbo].[REQUISITION_DETAILS] B ON C.RequestDetailsId = B.RequestDetailsId
              WHERE C.RequestNumber = A.RequestNumber AND C.EmployeeId = A.EmployeeId -- AND RequestStatus_hod = 'IN PROCESS'
              FOR XML PATH ('')), 1, 2, '') AS RequestQuantity,
       STUFF((SELECT ', ' + G.ItemName
              FROM [dbo].[REQUISITION] C 
              JOIN [dbo].[REQUISITION_DETAILS] B ON C.RequestDetailsId = B.RequestDetailsId 
              JOIN [dbo].[STOCK] F ON F.StockId = B.StockId 
              JOIN [dbo].[ITEM_MASTER] G ON F.ItemId = G.ItemId
              WHERE C.RequestNumber = A.RequestNumber AND C.EmployeeId = A.EmployeeId -- AND RequestStatus_hod = 'IN PROCESS'
              FOR XML PATH ('')), 1, 2, '') AS ItemNames,
       STUFF((SELECT ', ' + CAST(F.StockQuantity AS VARCHAR(255))
              FROM [dbo].[REQUISITION] C 
              JOIN [dbo].[REQUISITION_DETAILS] B ON C.RequestDetailsId = B.RequestDetailsId 
              JOIN [dbo].[STOCK] F ON F.StockId = B.StockId
              WHERE C.RequestNumber = A.RequestNumber AND C.EmployeeId = A.EmployeeId -- AND RequestStatus_hod = 'IN PROCESS'
              FOR XML PATH ('')), 1, 2, '') AS AvailableQuantity,
        STUFF((SELECT ', ' + B.RequestStatus_hod
               FROM [dbo].[REQUISITION] C 
               JOIN [dbo].[REQUISITION_DETAILS] B ON C.RequestDetailsId = B.RequestDetailsId
               WHERE C.RequestNumber = A.RequestNumber AND C.EmployeeId = A.EmployeeId -- AND RequestStatus_hod = 'IN PROCESS'
               FOR XML PATH ('')), 1, 2, '') AS RequestStatus_hods -- Temporary Column --
    FROM 
        [dbo].[REQUISITION] A
    JOIN
        [dbo].[USER] D ON D.EmployeeId = A.EmployeeId
    JOIN
        [dbo].[REQUISITION_DETAILS] E ON E.EmployeeId = D.EmployeeId
    WHERE 
        RequestStatus_hods = 'IN PROCESS' -- Col RequestStatus_hod FROM table REQUISITION_DETAILS --
    

    结果:

    enter image description here

4 个答案:

答案 0 :(得分:0)

尝试

WHERE E.RequestStatus_hod =' IN PROCESS'

答案 1 :(得分:0)

完全删除WHERE子句,然后尝试使用

JOIN
[dbo].[REQUISITION_DETAILS] E
ON E.EmployeeId = D.EmployeeId
AND E.RequestStatus_hod = 'IN PROCESS'

答案 2 :(得分:0)

一种解决方案是在WHERE子句中重复临时列的定义。 SQL Server不支持直接在WHERE中使用别名,但它仍然足够聪明(在大多数情况下),以确定表达式不需要被评估两次。因此,不要在RequestStatus_hod = 'IN PROCESS'内写WHERE,只需复制并粘贴列的实际定义,而不是RequestStatus_hods所在的位置。

但是,更好的选择可能是将列提取到APPLY子句中。这样,您肯定知道它不会运行两次。

例如:

SELECT DISTINCT 
   A.RequestNumber, A.EmployeeId,
   STUFF((SELECT ', ' + CAST(B.RequestDetailsId AS VARCHAR(255))
          FROM [dbo].[REQUISITION] C 
          JOIN [dbo].[REQUISITION_DETAILS] B ON C.RequestDetailsId = B.RequestDetailsId
          WHERE C.RequestNumber = A.RequestNumber AND C.EmployeeId = A.EmployeeId -- AND RequestStatus_hod = 'IN PROCESS'
          FOR XML PATH ('')), 1, 2, '') AS RequestDetailIds,
   STUFF((SELECT ', ' + CAST(B.StockId AS VARCHAR(255))
          FROM [dbo].[REQUISITION] C 
          JOIN [dbo].[REQUISITION_DETAILS] B ON C.RequestDetailsId = B.RequestDetailsId 
          JOIN [dbo].[STOCK] F ON F.StockId = B.StockId
          WHERE C.RequestNumber = A.RequestNumber AND C.EmployeeId = A.EmployeeId -- AND RequestStatus_hod = 'IN PROCESS'
          FOR XML PATH ('')), 1, 2, '') AS StockIds,
   STUFF((SELECT ', ' + CAST(B.RequestQuantity AS VARCHAR(255))
          FROM [dbo].[REQUISITION] C 
          JOIN [dbo].[REQUISITION_DETAILS] B ON C.RequestDetailsId = B.RequestDetailsId
          WHERE C.RequestNumber = A.RequestNumber AND C.EmployeeId = A.EmployeeId -- AND RequestStatus_hod = 'IN PROCESS'
          FOR XML PATH ('')), 1, 2, '') AS RequestQuantity,
   STUFF((SELECT ', ' + G.ItemName
          FROM [dbo].[REQUISITION] C 
          JOIN [dbo].[REQUISITION_DETAILS] B ON C.RequestDetailsId = B.RequestDetailsId 
          JOIN [dbo].[STOCK] F ON F.StockId = B.StockId 
          JOIN [dbo].[ITEM_MASTER] G ON F.ItemId = G.ItemId
          WHERE C.RequestNumber = A.RequestNumber AND C.EmployeeId = A.EmployeeId -- AND RequestStatus_hod = 'IN PROCESS'
          FOR XML PATH ('')), 1, 2, '') AS ItemNames,
   STUFF((SELECT ', ' + CAST(F.StockQuantity AS VARCHAR(255))
          FROM [dbo].[REQUISITION] C 
          JOIN [dbo].[REQUISITION_DETAILS] B ON C.RequestDetailsId = B.RequestDetailsId 
          JOIN [dbo].[STOCK] F ON F.StockId = B.StockId
          WHERE C.RequestNumber = A.RequestNumber AND C.EmployeeId = A.EmployeeId -- AND RequestStatus_hod = 'IN PROCESS'
          FOR XML PATH ('')), 1, 2, '') AS AvailableQuantity,
    xx.RequestStatus_hods -- Temporary Column --
FROM 
    [dbo].[REQUISITION] A
JOIN
    [dbo].[USER] D ON D.EmployeeId = A.EmployeeId
JOIN
    [dbo].[REQUISITION_DETAILS] E ON E.EmployeeId = D.EmployeeId
CROSS APPLY 
    (SELECT STUFF((SELECT ', ' + B.RequestStatus_hod
           FROM [dbo].[REQUISITION] C 
           JOIN [dbo].[REQUISITION_DETAILS] B ON C.RequestDetailsId = B.RequestDetailsId
           WHERE C.RequestNumber = A.RequestNumber AND C.EmployeeId = A.EmployeeId 
           FOR XML PATH ('')), 1, 2, '') as RequestStatus_hods) xx
WHERE 
    xx.RequestStatus_hods = 'IN PROCESS' -- Col RequestStatus_hod FROM table REQUISITION_DETAILS --

答案 3 :(得分:0)

Ok首先,让我们用他们的名字调用一些东西,RequestStatus_hods不是一个“临时列”,它是一个计算放在查询结果集的一列中,别名是“RequestStatus_hods”。

我真的不了解那些涉及CROSS JOINS的解决方案,所以我无法对它们进行评估,但我认为在这些情况下性能并不是最好的。

对于这类问题,我有两种不同的方法 1.-而不是where子句中的“RequestStatus_hods”,使用与用于在列中构建值的完全相同的表达式。它可以工作,但如果结果集包含大量记录,性能将受到影响。 2.-我将查询包围如下

SELECT * FROM ( <YOUR-QUERY> ) AS 
RESULTSET WHERE RESULTSET.[RequestStatus_hods] = 'IN PROCESS'

因此,您的查询将成为一个内部组成的临时表(取决于引擎解析查询的对象),但效果是您拥有所需的表以及所需的字段。这种方法的表现通常不是很糟糕。

希望这有帮助。