2017-04-13 80 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或視圖工作。