当按组嵌套选择时,列名称无效

时间:2012-07-16 20:21:13

标签: sql tsql

我有以下代码,当我运行它时,它会将我想要的数据返回给我:

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' 

当我想要将一个组添加到其中一个列时,问题就出现了。然后它会抛出一个错误,说该列不存在,但是当我运行查询而没有Group By the column和name存在时。

以下是我遇到问题的代码组:

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如何解决它。

2 个答案:

答案 0 :(得分: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 :(得分: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 JOIN位置更改为INNER JOIN,因为你有AND CostCenter IS NOT NULL因此LEFT JOININNER 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 获得相同的结果。这应该可以提高执行效率:

{{1}}