2014-05-13 70 views
3

我掙扎編寫以下情形的SQL查詢創建一個從表中的矩陣型結果和任何指針將不勝感激:如何使用SQL

我已經存儲了這樣的我的數據:

 
Zone Name | SessionId 
Zone 1 | 1 
Zone 2 | 1 
Zone 3 | 1 
Zone 1 | 1 
Zone 1 | 2 
Zone 2 | 2 
Zone 2 | 3 
Zone 3 | 3 
Zone 2 | 3 

(注意,人們可以在會話中不止一次進入同一區域)

我想產生一個輸出,顯示誰,已進入一個區域的人的百分比,也進入了另一個(即66%進入1區的人也進入2區):

 
     Zone 1 | Zone 2 | Zone 3 
Zone 1 100% | 66% | 33% 
Zone 2 66% | 100% | 66% 
Zone 3 33% | 66% | 100% 

是否有一個特定的內置SQL函數來做這樣的事情?任何人都可以就如何實現這一目標提供任何建議?

感謝 湯姆

附:使用PostgreSQL

小提琴這裏:http://sqlfiddle.com/#!15/f379c/1/0

+0

你會使用'交叉表()'函數來做到這一點。但請澄清你的問題,因爲它含糊不清。你說,「進入區域的sessionid,此sessionid輸入了多少個其他區域」。但是你給的桌子是不同的。這就像「在一次會議中所有參賽作品中,訪問了多少個不同區域」。區域1 => {1,1,2},區域2 => {1,2,3,3}。因此,Zone 1 - > 2 = 2個共同參與2個唯一ID的區域1 = 100%(您的敘述)或2個共同區域1 = 66%(您的桌子)。那它是哪一個? – Patrick

回答

1

所以,如果你能處理應用方面的一些轉變:

DECLARE @ZoneCounts TABLE 
    (
    Zone nvarchar(max), 
    sessionId int 
    ) 

INSERT INTO @ZoneCounts 
values 
('Zone 1', 1), 
('Zone 2', 1), 
('Zone 3', 1), 
('Zone 1', 2), 
('Zone 2', 2) 

select v3.down, v3.across, convert(decimal(13,2),(CONVERT(decimal(13,2), v3.matchingSessions)/v3.sessionsVisitingDown) * 100) as percentage 
from 
(SELECT v2.down, v2.across, v2. matchingSessions, max(v2.matchingSessions) over (partition by v2.down) as sessionsVisitingDown 
FROM (select down, across, matchingSessions from 
(select lhs.Zone as down, rhs.Zone as across, count(lhs.sessionId) over (partition by lhs.Zone, rhs.Zone) as matchingSessions 
from @ZoneCounts as lhs inner join @ZoneCounts as rhs on lhs.sessionId = rhs.sessionId) AS v1 
GROUP BY down, across, matchingSessions) AS v2) 
as v3 

給你

enter image description here

NB - 採用MS SQL但應該轉換成


啊,Postgres的是不太一樣

SELECT v3.down, v3.across, cast(cast(v3.matchingSessions as decimal)/cast(v3.sessionsVisitingDown as decimal) * 100 as decimal(13,2)) AS percentage 
FROM 
(SELECT v2.down, v2.across, v2. matchingSessions, max(v2.matchingSessions) over (partition BY v2.down) AS sessionsVisitingDown 
FROM (SELECT down, across, matchingSessions FROM 
(SELECT lhs.name AS down, rhs.name AS across, count(lhs.id) over (partition BY lhs.name, rhs.name) AS matchingSessions 
FROM ItemList AS lhs INNER JOIN ItemList AS rhs ON lhs.id = rhs.id) AS v1 
GROUP BY down, across, matchingSessions) AS v2) 
AS v3 

這裏有一個SQL小提琴:http://sqlfiddle.com/#!15/f379c/13/0使用PostgreSQL