简体   繁体   中英

Alias scoping in a (Correlated) subquery embedded in the select statement

My work is running SQL Server 2008 and I spend a lot of time querying the database for information as a side piece to my job. If I need information that isn't at the same aggregate level as my dataset I use an embedded query in the select statement. Usually it's 2 or 3 slightly different versions of the same number, so they both query the same tables. (See example below)

The question is what is the scoping of the aliases for the subqueries embedded in a select statement . The two options I've thought of are:

  1. At the Script level and must be unique to all subqueries and tables?
  2. At the Subquery level and can share the same aliases in each.

I know for tables aliased in the From statement they must be unique. I thought that the fact that the queries were executing on each row generation that it might be a different situation.

Examples (completely made up, let me know any obvious errors and I'll correct them):

Script Level - unique aliases for all subqueries and tables:

Select
  p.purchaseid, p.purchasedate, 
  s.storename, c.customerid, 
(select count(p2.purchaseid) 
  from purchases p2 inner join 
       store s2 on p2.storeid = s2.storeid
  where s2.storeid = s.storeid
    and p2.purchasedate = p.purchasedate) as 'Store Daily Total Purchases',
(select count(p3.purchaseid) 
  from purchases p3 inner join 
       store s3 on p3.storeid = s3.storeid
  where p3.customerid = p.customerid
    and p3.purchasedate = p.purchasedate) as 'Customer Daily Total Purchases'
from 
  purchases p inner join   
  customer c on p.customerid = c.customerid
  store s on p.storeid = s.storeid

Query Level - common aliases for subqueries ok:

Select
  p.purchaseid, p.purchasedate, 
  s.storename, c.customerid, 
(select count(p2.purchaseid) 
  from purchases p2 inner join 
       store s2 on p2.storeid = s2.storeid
where s2.storeid = s.storeid
  and p2.purchasedate = p.purchasedate) as 'Store Daily Total Purchases',
(select count(p2.purchaseid) 
  from purchases p2 inner join 
       store s2 on p2.storeid = s2.storeid
where p2.customerid = p.customerid
  and p2.purchasedate = p.purchasedate) as 'Customer Daily Total Purchases'
from 
  purchases p inner join   
  customer c on p.customerid = c.customerid
  store s on p.storeid = s.storeid

The aliasing is at the query level, so your second example is fine.

The reference to the tables in the from clause makes these correlated subqueries, in case you want to read more about that topic.

In general, I recommend that you move the queries to the from clause and manage them as joins:

Select p.purchaseid, p.purchasedate, s.storename, c.customerid,
       pdate.cnt as [Store Daily Total Purchases],
       pcust.cnt as [Customer Daily Total Purchases]
from purchases p inner join   
     customer c
     on p.customerid = c.customerid join
     store s on p.storeid = s.storeid left outer join
     (select s2.storeid, p2.purchasedate, count(p2.purchaseid) 
      from purchases p2 inner join 
           store s2 on p2.storeid = s2.storeid
      group by s2.storeid, p2.purchasedate
     ) pdate
     on pdate.purchasedate = p.purchasedate and
        pdate.storeid = s.storeid left outer join
     (select s2.customerid, p2.purchasedate, count(p2.purchaseid) 
      from purchases p2 inner join 
           store s2 on p2.storeid = s2.storeid
      group by s2.storeid, p2.purchasedate
     ) pcust
     on pcust.purchasedate = p.purchasedate and
        pcust.customerid= s.customerid

However, in your case, I think there is a simpler solution just using aggregation:

Select p.purchaseid, p.purchasedate, s.storename, c.customerid,
       count(*) over (partition by s.storeid, p.purchasedate) as  as [Store Daily Total Purchases],
       count(*) over (partition by c.customerid, p.purchasedate) as [Customer Daily Total Purchases]
from purchases p inner join   
     customer c
     on p.customerid = c.customerid join
     store s on p.storeid = s.storeid

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