2012-07-16 75 views
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' 

問題是當我要添加按其中一列分組。然後它會拋出一個錯誤,說該列不存在,但是當我運行沒有該組的列時,該列和名稱存在。

下面是組由我遇到的問題代碼:

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圖瞭解如何解決它。

+1

您可能需要將整個子句放入GROUP BY;我不認爲它可以使用別名。 – 2012-07-16 20:25:36

回答

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 
1

您可以使用的T-SQL APPLY此功能,它類似於你已經使用,但可以參考多個相關子查詢次而不重複相同的代碼,並且如果需要也可以返回多個列/行。

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 JOININNER JOIN因爲你有AND CostCenter IS NOT NULL因此一個LEFT JOIN不是必需的,INNER JOIN旨意更好的表現。其次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