2016-02-25 27 views
0

我仍然可以通過SQL涉水我的方式(我覺得我會永遠這樣!)報告中的多個值一米田

我想選擇客戶和展示他們走過的所有地方到,可能會超過1個,並按年逐列列出。

例子:

name 2014 2015  2016 
bob  japan korea  Mexico 
     Tucson England 
Dennis Paris England China 
     Texas Canada 
       Portland 

我有:

SELECT name, 
    (SELECT location from places where year = '2014') AS '2014', 
    (SELECT location from places where year = '2015') AS '2015', 
    (SELECT location from places where year = '2014') AS '2016' 
FROM customer 
JOIN places 
on places.customerID = customer.customerID 

很抱歉的僞代碼;我現在正在旅行,但這一直在困擾着我好幾天。我覺得我的語法或方法是錯誤的...

非常感謝您的指導!

+0

有沒有「感覺」一下 - 它或者按照預期的方式工作。我懷疑當你運行這個時,你會得到'子查詢返回多個值'的錯誤,但是看起來你還沒有真正運行它?你在這裏之後是一個交叉表。 –

+0

@ Nick.McDermaid啊!是!我希望能夠連接並運行它!我想我也會得到這個錯誤。哦!交叉!謝謝你在這個方向的重點! – Jim

回答

0

如果您嘗試使用子查詢作爲表達式並返回多條記錄,那麼SQL Server會發出抱怨。你會看到錯誤:

Msg 512, Level 16, State 1, Line 3 Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= ,> >, >= or when the subquery is used as an expression.

就你而言,你在主要的select語句中使用子查詢作爲表達式。

您的輸出結果通常是您想要在報告或應用程序層完成的。這不是SQL擅長的,但可能的。然而,有一點可以幫助您創建一個包含每個客戶和每年的地點列表的字段。 FOR XML子句擅長將許多值濃縮爲列表或xml值。下面是一個例子,它創建了一個逗號分隔的位置列表,但您可以使用任何你喜歡的分隔符。

create table #customer (customerID int, name varchar(50)) 
create table #places (customerID int, year int, location varchar(50)) 

insert into #customer values (1, 'Bob') 
insert into #customer values (2, 'Dennis') 

insert into #places values (1, 2014, 'Japan') 
insert into #places values (1, 2014, 'Tucon') 
insert into #places values (2, 2014, 'Paris') 
insert into #places values (2, 2014, 'Texas') 
insert into #places values (1, 2015, 'Korea') 
insert into #places values (1, 2015, 'England') 
insert into #places values (2, 2015, 'England') 
insert into #places values (2, 2015, 'Canada') 
insert into #places values (2, 2015, 'Portland') 
insert into #places values (1, 2016, 'Mexico') 
insert into #places values (2, 2016, 'China') 

select name, year, 
    STUFF(
     (select ',' + location 
     from #places 
     where #places.customerID = c.customerID 
      and #places.year = p.year 
     for XML Path('') 
     ) 
     , 1, 1, '' 
    ) AS locations 
FROM #customer c 
JOIN #places p 
on p.customerID = c.customerID 
group by c.name, c.customerID, p.year 

然後從這種數據格式,你可以做更多的事情像你上面的查詢,因爲位置正好是每一個客戶/年組合的價值。您還可以在SQL Server中使用PIVOT功能,但您可能再次可以在報告圖層中執行此操作。例如使用在Excel中旋轉的功能,報表服務...等

0

使用條件與聚集到ROW_NUMBER達到預期的效果:

;WITH Cte AS(
    SELECT c.name,p.*, 
     rn = ROW_NUMBER() OVER(PARTITION BY c.customerID, p.year ORDER BY (SELECT NULL)) 
    FROM customer c 
    INNER JOIN places p 
     ON p.customerID = c.customerID 
) 
SELECT 
    name = CASE WHEN rn = 1 THEN name ELSE '' END, 
    [2014] = MAX(CASE WHEN c.year = '2014' THEN c.location ELSE '' END), 
    [2015] = MAX(CASE WHEN c.year = '2015' THEN c.location ELSE '' END), 
    [2016] = MAX(CASE WHEN c.year = '2016' THEN c.location ELSE '' END) 
FROM Cte c 
GROUP BY c.customerID, c.name, c.rn 
ORDER BY c.name, c.customerID 

TRY IT HERE

+0

這個工作真的很好,我不知道ROW_NUMBER()謝謝! – Jim

相關問題