如何向此游标添加子查询?

时间:2013-11-22 12:51:36

标签: sql sql-server group-by cursor

我尝试将子查询(StoCount)添加到以下游标:

        DECLARE trans_cur CURSOR FOR
        SELECT b.TransportNumber, 
            SUM(CASE WHEN a.DeliveryItemStatus = 'C' OR a.DeliveryItemStatus = 'V' THEN 1 ELSE 0 END) AS Completed, 
            COUNT(*) AS Total,
            SUM(CASE WHEN a.DeliveryItemStatus = 'F' THEN 1 ELSE 0 END) AS Missing,
            (SELECT COUNT(*) FROM StorageTransportOrderItem WHERE DeliveryNumber = a.DeliveryNumber AND DeliveryItemNumber = a.DeliveryItemNumber)  As StoCount
           FROM DeliveryItem a
           INNER JOIN TransportItem b on a.DeliveryNumber = b.DeliveryNumber
           INNER JOIN Material c on a.MaterialNumber = c.MaterialNumber
           INNER JOIN Transport d on b.TransportNumber = d.TransportNumber
           WHERE a.StorageLocationNumber IS NOT NULL
                AND a.Deleted <> 1
                AND c.CommissioningArea LIKE @commissioningArea 
                AND d.TransportStatus < 70
           GROUP BY b.TransportNumber

但是当我总是收到错误消息时:

  

Msg 8120,Level 16,State 1,Procedure sp_CalculateTransportProgress,   第41行列'DeliveryItem.DeliveryNumber'在select中无效   list,因为它不包含在聚合函数中   GROUP BY子句。 Msg 8120,Level 16,State 1,Procedure   sp_CalculateTransportProgress,第41行专栏   “DeliveryItem.DeliveryItemNumber”在选择列表中无效   因为它不包含在聚合函数或   GROUP BY子句。

我的目标是将这个单列(StoCount)添加到游标而不会过多地修改查询。 这可能吗?

1 个答案:

答案 0 :(得分:3)

您可以将相关子查询移动到cross apply

SELECT b.TransportNumber, 
        SUM(CASE WHEN a.DeliveryItemStatus = 'C' OR a.DeliveryItemStatus = 'V' THEN 1 ELSE 0 END) AS Completed, 
        COUNT(*) AS Total,
        SUM(CASE WHEN a.DeliveryItemStatus = 'F' THEN 1 ELSE 0 END) AS Missing,
        MAX(e.Freq) AS StoCount
FROM DeliveryItem a
INNER JOIN TransportItem b on a.DeliveryNumber = b.DeliveryNumber
INNER JOIN Material c on a.MaterialNumber = c.MaterialNumber
INNER JOIN Transport d on b.TransportNumber = d.TransportNumber
CROSS APPLY (
    SELECT COUNT(*) freq FROM StorageTransportOrderItem  s
    WHERE s.DeliveryNumber = a.DeliveryNumber AND s.DeliveryItemNumber = a.DeliveryItemNumber
) e
WHERE a.StorageLocationNumber IS NOT NULL
  AND a.Deleted <> 1
  AND c.CommissioningArea LIKE @commissioningArea 
  AND d.TransportStatus < 70
GROUP BY b.TransportNumber

按xsl编辑:

我不得不稍微修改一下查询,以便它为我的数据库返回正确的结果:

        SELECT b.TransportNumber, 
                SUM(CASE WHEN a.DeliveryItemStatus = 'C' OR a.DeliveryItemStatus = 'V' THEN 1 ELSE 0 END) AS Completed, 
                COUNT(*) AS Total,
                SUM(CASE WHEN a.DeliveryItemStatus = 'F' THEN 1 ELSE 0 END) AS Missing,
                SUM(e.Freq) AS StoCount
        FROM DeliveryItem a
        INNER JOIN TransportItem b on a.DeliveryNumber = b.DeliveryNumber
        INNER JOIN Material c on a.MaterialNumber = c.MaterialNumber
        INNER JOIN Transport d on b.TransportNumber = d.TransportNumber
        CROSS APPLY (
            SELECT COUNT(1) freq FROM StorageTransportOrderItem s
            WHERE 
                s.DeliveryNumber = a.DeliveryNumber
                AND s.DeliveryItemNumber = a.DeliveryItemNumber
                AND s.MaterialNumber = a.MaterialNumber
        ) e
        WHERE a.StorageLocationNumber IS NOT NULL
          AND a.Deleted <> 1
          AND c.CommissioningArea LIKE @commissioningArea 
          AND d.TransportStatus < 70
        GROUP BY b.TransportNumber