0

次のコードがあります。そのまま実行すると、必要なデータが返されます。

select tagid, 
  (select TOP 1 Locations.CostCenter
  from item
  inner join transactions on transactions.itemid = item.id 
  inner join recvlocationmapping on recvlocationid = transactions.locationid 
  left outer join locations on locations.id = servicelocationid  
  where tagid = c.TagID
  and costcenter != '' 
  and Costcenter is not null 
  order by transdate desc) as CostCenter
from item as c where createddate between '07-01-2012' and '07-05-2012' 

問題は、列の 1 つに group by を追加したいときに発生します。次に、列が存在しないというエラーがスローされますが、グループ化なしでクエリを実行すると、列と名前が存在します。

私が問題を抱えているコードによるグループは次のとおりです。

select Count(tagid), 
  (select TOP 1 Locations.CostCenter
  from item
  inner join transactions on transactions.itemid = item.id 
  inner join recvlocationmapping on recvlocationid = transactions.locationid 
  left outer join locations on locations.id = servicelocationid  
  where tagid = c.TagID
  and costcenter != '' 
  and Costcenter is not null 
  order by transdate desc) as CostCenter
from item as c where createddate between '07-01-2012' and '07-05-2012'
group by CostCenter

データを返す方法に問題があると思いますが、それを修正する方法を理解するのに十分な SQL の知識がありません。

4

2 に答える 2

2

一部で宣言されたエイリアスは、 ではselect ...使用できませんgroup by。ネストされた選択を複製するか、group by次のようなものを使用する必要があります。

select Count(q.tagid), q.CostCenter
from
    (select 
       tagid, 
       (select TOP 1 Locations.CostCenter
           from item
           inner join transactions on transactions.itemid = item.id 
           inner join recvlocationmapping on recvlocationid = transactions.locationid 
           left outer join locations on locations.id = servicelocationid  
           where tagid = c.TagID
           and costcenter != '' 
           and Costcenter is not null 
           order by transdate desc
       ) as CostCenter
       from item as c where createddate between '07-01-2012' and '07-05-2012'
    ) q
group by q.CostCenter
于 2012-07-16T20:27:34.973 に答える
1

ここでT-SQLAPPLY機能を利用できます。これは、使用した相関サブクエリに似ていますが、同じコードを繰り返さずに複数回参照でき、必要に応じて複数の列/行を返すこともできます。

SELECT  COUNT(tagid), 
        CostCenter
FROM    item as c 
        OUTER APPLY
        (   SELECT  TOP 1 Locations.CostCenter
            FROM    item
                    INNER JOIN transactions 
                        ON transactions.itemid = item.id 
                    INNER JOIN recvlocationmapping 
                        ON recvlocationid = transactions.locationid 
                    INNER JOIN locations 
                        ON locations.id = servicelocationid  
            WHERE   tagid = c.TagID
            AND     costcenter != '' 
            ORDER BY transdate DESC
        ) AS CostCenter
WHERE   createddate BETWEEN '07-01-2012' AND '07-05-2012'
GROUP BY CostCenter

また、サブクエリのいくつかを修正しました。LEFT JOINon の場所を anに変更しましINNER JOINた。AND CostCenter IS NOT NULLそのため、 aLEFT JOINは不要であり、INNER JOINs のパフォーマンスが向上します。第二に、次の理由AND CostCenter IS NOT NULLで冗長でしたAND CostCenter != ''NULL != ''

編集

さらに考えてみると、相関サブクエリを完全に削除して、 を使用して同じ結果を得ることができると思いますJOINS。これにより、実行がより効率的になります。

;WITH CostCenter AS
(   SELECT  TagID, CostCenter, ROW_NUMBER() OVER(PARTITION BY TagID ORDER BY TransDate DESC) AS RowNumber
    FROM    item
            INNER JOIN transactions 
                ON transactions.itemid = item.id 
            INNER JOIN recvlocationmapping 
                ON recvlocationid = transactions.locationid 
            INNER JOIN locations 
                ON locations.id = servicelocationid  
    WHERE   costcenter != '' 
)
SELECT  COUNT(TagID), CostCenter
FROM    Item
        INNER JOIN CostCenter
            ON Item.TagID = CostCenter.TagID
            AND RowNumber = 1
WHERE   createddate BETWEEN '07-01-2012' AND '07-05-2012'
GROUP BY CostCenter
于 2012-07-16T21:33:43.303 に答える