I have the following code, when I run it as is it will return to me the data I would like:
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'
The problem comes when I want to add a group by to one of the columns. It then throws a error saying the column doesn't exist, but when I run the query without the Group By the column and name exist.
Here is the group by code that I'm having issues with:
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
I think it's an issue with how I'm returning the data, but I don't know enough about SQL to figure out how to fix it.
Aliases declared in select ...
part cannot be used in group by
. You either have to duplicate nested select in group by
or use something like this:
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
You can make use of the T-SQL APPLY
functionality here, it is similar to the correlated subquery you have used but can be referenced multiple times without repeating the same code, and can also return multiple columns/rows if required.
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
I've also touched up a couple of things on your subquery, I changed the LEFT JOIN
on locations to an INNER JOIN
since you had AND CostCenter IS NOT NULL
therefore a LEFT JOIN
was not required and INNER JOIN
s will perform better. Secondly AND CostCenter IS NOT NULL
was redundant following AND CostCenter != ''
because NULL != ''
EDIT
Upon further thought I think you can remove the correlated subqueries from it completely and get the same result using JOINS
. This should result in more efficient execution:
;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
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.