2017-04-13 52 views
1

我创造了这个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”次尽可能多的产品因为有。我希望能够对类别应用“跳过并采取”方法,但是查询返回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 

但是我得到的一个编译时错误:

列 'ID' 被指定多次为 'V'。

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

回答

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 
+0

谢谢您的回答,无论我们是对的,但你的额外意见中提出单击它,我当然就是这个道理 –

+0

@ Jono_2007快乐帮的实现! – SqlZim

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或视图工作。