从子查询

时间:2017-04-13 21:46:14

标签: sql sql-server

我创建了这个SQL:

SELECT 
    DENSE_RANK() OVER (ORDER BY c1.Id) as [rank], 
    C1.Id, C1.Name, 
    P2.Id, P2.Name, P2.CategoryId  
FROM 
    Category C1  
LEFT OUTER JOIN 
    Product P2 ON C1.Id = P2.Id

因此,这将返回4个将被复制的类别' N'是有多少产品。我希望能够应用" Skip and Take"但是对于类别的方法,当查询返回N + 1时,这不可能通过常规方法实现。

我希望能够使用DENSE_RANK来执行此操作,但这是不可能的,因为来自DENSE_RANK的计算无法在WHERE中使用。

我提出了这个SQL:

SELECT  
    v.*
FROM 
    (SELECT 
         DENSE_RANK() OVER (ORDER BY c1.Id) as [rank], 
         C1.Id, C1.Name, 
         P2.Id, P2.Name, P2.CategoryId  
     FROM 
         Category C1  
     LEFT OUTER JOIN 
         Product P2 ON C1.Id = P2.Id) v
WHERE 
    v.rank > 0 AND v.rank < 4

但是我的编译时错误是:

  

列&#39; Id&#39;被多次指定为&#39; v&#39;。

这不是原始查询的问题,产品和类别都有Id,但第一个查询已执行并返回了预期结果。这突然成为第二个查询的问题,我不确定为什么。

2 个答案:

答案 0 :(得分:2)

列名称必须是唯一的。使用别名:

SELECT DENSE_RANK() OVER (ORDER BY c1.Id) as [rank], 
       C1.Id as c_id, C1.Name as c_name, 
       P2.Id as p_id, P2.Name as p_name, P2.CategoryId
FROM Category C1 LEFT OUTER JOIN
     Product P2 
     ON C1.Id = P2.Id;

然后,它可以作为子查询,CTE或视图。

答案 1 :(得分:1)

因为如果您添加where ... and v.id = 2,那么它会过滤哪个列?您可以在将列添加到结果集之前使用as对列进行别名。

SELECT v.*
FROM (
    SELECT DENSE_RANK() OVER (ORDER BY c1.Id) as [rank], 
    C1.Id as CId, C1.Name as CName, 
    P2.Id as Pid, P2.Name as PName, P2.CategoryId  
    FROM Category C1  
      LEFT OUTER JOIN Product P2 
        ON C1.Id = P2.Id
  ) v
WHERE v.rank > 0 AND v.rank < 4