简体   繁体   中英

How can I add a sub-query to this cursor?

I tried to add a sub query (StoCount) to the following cursor:

        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

but when I always get the error message:

Msg 8120, Level 16, State 1, Procedure sp_CalculateTransportProgress, Line 41 Column 'DeliveryItem.DeliveryNumber' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. Msg 8120, Level 16, State 1, Procedure sp_CalculateTransportProgress, Line 41 Column 'DeliveryItem.DeliveryItemNumber' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

My goal is to add this single column (StoCount) to the cursor without modifying the query too much. Is that possible?

You could move the correlated subquery to a 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

Edit by xsl:

I had to modify the query a bit, so that it returned the correct results for my database:

        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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM