2015-11-19 34 views
8

我建设使用D3.js显示我的应用程序中连接的电话号码到六度分隔的网络分析。用于查找初始连接的SQL(postgres)在下面并且非常简单。然而,我很难理解如何修改这个遍历六个级别的连接,然后停下来。SQL查询6分离度网络分析

SELECT player_id, ps.player_state, ps.email, ph.create_date 
FROM game.phone_hashes ph 
INNER JOIN game.customer_settings cs ON cs.id = ph.player_id 
WHERE hash IN (SELECT hash FROM game.phone_hashes WHERE player_id = $1); 

我发现通过研究提到公用表表达式(CTE)和递归到这个问题,但我不确定如何将它们适用于此。

我的目标是让所有的玩家通过常见的电话散列表连接到初始玩家(1美元),然后通过普通的电话散列表连接到每个连接的所有玩家,达到6度的分离度。

+7

请编辑您的问题,并添加定义('create table')所涉及的表格。 –

+0

此外,它往往有助于理解这个问题,如果这个问题了一个例子 - 数据的几行,什么查询的结果应基于此样本数据。 –

+0

A **表定义**就是你'在psql的\ d game.phone_hashes'得到。或完整的CREATE TABLE脚本。 –

回答

7

我觉得这是你的意思:

with recursive tc as(
select $1 as player_id, 1 as level 
    union 
select ph2.player_id, level+1 
    from tc, phone_hashes ph1, phone_hashes ph2 
    where tc.player_id=ph1.player_id 
    and ph1.hash=ph2.hash 
    and tc.level < 6 
)  
select distinct player_id from tc 
4

认为这将是:

-- 6 degrees of separation 
SELECT player_id, ps.player_state, ps.email, ph.create_date 
FROM game.phone_hashes ph 
INNER JOIN game.customer_settings cs ON cs.id = ph.player_id 
WHERE hash IN 
(SELECT hash FROM game.phone_hashes 
WHERE hash IN 
(SELECT hash FROM game.phone_hashes 
    WHERE hash IN 
    (SELECT hash FROM game.phone_hashes 
    WHERE hash IN 
    (SELECT hash FROM game.phone_hashes 
    WHERE hash IN 
    (SELECT hash FROM game.phone_hashes 
    WHERE hash IN 
    (SELECT hash FROM game.phone_hashes 
     WHERE player_id = $1)))))); 

请参见下面的工作方式:

-- 1 degree of separation 
SELECT player_id, ps.player_state, ps.email, ph.create_date 
FROM game.phone_hashes ph 
INNER JOIN game.customer_settings cs ON cs.id = ph.player_id 
WHERE hash IN 
(SELECT hash FROM game.phone_hashes WHERE player_id = $1); 

-- 2 degrees of separation 
SELECT player_id, ps.player_state, ps.email, ph.create_date 
FROM game.phone_hashes ph 
INNER JOIN game.customer_settings cs ON cs.id = ph.player_id 
WHERE hash IN 
(SELECT hash FROM game.phone_hashes 
WHERE hash IN 
(SELECT hash FROM game.phone_hashes 
    WHERE player_id = $1)); 

-- 3 degrees of separation 
SELECT player_id, ps.player_state, ps.email, ph.create_date 
FROM game.phone_hashes ph 
INNER JOIN game.customer_settings cs ON cs.id = ph.player_id 
WHERE hash IN 
(SELECT hash FROM game.phone_hashes 
WHERE hash IN 
(SELECT hash FROM game.phone_hashes 
    WHERE hash IN 
    (SELECT hash FROM game.phone_hashes 
    WHERE player_id = $1))); 

-- 4 degrees of separation 
SELECT player_id, ps.player_state, ps.email, ph.create_date 
FROM game.phone_hashes ph 
INNER JOIN game.customer_settings cs ON cs.id = ph.player_id 
WHERE hash IN 
(SELECT hash FROM game.phone_hashes 
WHERE hash IN 
(SELECT hash FROM game.phone_hashes 
    WHERE hash IN 
    (SELECT hash FROM game.phone_hashes 
    WHERE hash IN 
    (SELECT hash FROM game.phone_hashes 
    WHERE player_id = $1)))); 


-- 5 degrees of separation 
SELECT player_id, ps.player_state, ps.email, ph.create_date 
FROM game.phone_hashes ph 
INNER JOIN game.customer_settings cs ON cs.id = ph.player_id 
WHERE hash IN 
(SELECT hash FROM game.phone_hashes 
WHERE hash IN 
(SELECT hash FROM game.phone_hashes 
    WHERE hash IN 
    (SELECT hash FROM game.phone_hashes 
    WHERE hash IN 
    (SELECT hash FROM game.phone_hashes 
    WHERE hash IN 
    (SELECT hash FROM game.phone_hashes 
    WHERE player_id = $1))))); 

-- 6 degrees of separation 
SELECT player_id, ps.player_state, ps.email, ph.create_date 
FROM game.phone_hashes ph 
INNER JOIN game.customer_settings cs ON cs.id = ph.player_id 
WHERE hash IN 
(SELECT hash FROM game.phone_hashes 
WHERE hash IN 
(SELECT hash FROM game.phone_hashes 
    WHERE hash IN 
    (SELECT hash FROM game.phone_hashes 
    WHERE hash IN 
    (SELECT hash FROM game.phone_hashes 
    WHERE hash IN 
    (SELECT hash FROM game.phone_hashes 
    WHERE hash IN 
    (SELECT hash FROM game.phone_hashes 
     WHERE player_id = $1))))));