别名在select语句中嵌入的(Correlated)子查询中作用域

时间:2012-06-22 22:54:42

标签: sql sql-server database sql-server-2008 subquery

我的工作是运行SQL Server 2008,我花了很多时间查询数据库,以获取信息作为我工作的副本。如果我需要与我的数据集不在同一聚合级别的信息,我在select语句中使用嵌入式查询。通常它是相同数字的2或3个略有不同的版本,因此它们都查询相同的表。 (见下面的例子)

问题是嵌入在select语句中的子查询的别名的范围是什么。我想到的两个选项是:

  1. 在脚本级别,并且必须对所有子查询都是唯一的 表?
  2. 在Subquery级别,可以共享相同的别名 每个
  3. 我知道在From语句中有别名的表,它们必须是唯一的。我认为查询在每一行上执行的事实可能是不同的情况。

    示例(完全组成,让我知道任何明显的错误,我会纠正它们):

    脚本级别 - 所有子查询和表的唯一别名:

    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
    

    查询级别 - 子查询的常见别名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
    

1 个答案:

答案 0 :(得分:3)

别名是在查询级别,所以你的第二个例子没问题。

对from子句中的表的引用会产生这些相关的子查询,以防您想要阅读有关该主题的更多信息。

通常,我建议您将查询移至from子句并将其作为连接进行管理:

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

但是,在您的情况下,我认为只使用聚合有一个更简单的解决方案:

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