如何使用 SQL 将 table 转换为节点对

How to transform a table into node pairs using SQL

我有一个针对用户点击而构建的数据库。每次有人从一个网站点击访问另一个网站时,我都会捕获用户名、网站以及他们点击路径中的点击。它看起来像这样:

+----------+-------+---------------+
| Customer | Click | Website       |
+----------+-------+---------------+
| john     | 1     | facebook      |
+----------+-------+---------------+
| john     | 2     | microsoft     |
+----------+-------+---------------+
| john     | 3     | facebook      |
+----------+-------+---------------+
| steven   | 1     | apple         |
+----------+-------+---------------+
| steven   | 2     | Whosebug |
+----------+-------+---------------+
| steven   | 3     | cnn           |
+----------+-------+---------------+  

我想可视化人们如何在互联网上四处走动。我相信节点路径是最好的主意,但我不确定如何将这些数据转换成那个。对于节点值对,必须将上面的 table 操作为如下所示:

+----------+----------------+-----------------+
| Customer | Origin Website | Landing Website |
+----------+----------------+-----------------+
| john     | facebook       | microsoft       |
+----------+----------------+-----------------+
| john     | microsoft      | facebook        |
+----------+----------------+-----------------+
| steven   | apple          | Whosebug   |
+----------+----------------+-----------------+
| steven   | Whosebug  | cnn             |
+----------+----------------+-----------------+  

是否可以仅使用 oracle SQL?

您可以使用 LEAD():

Select  Customer, 
        Website As "Origin Website",
        Lead(Website) Over (Partition By Customer Order By Click) As "Landing Website"
From    YourTable

像这样。我添加了一列来显示 "hops" 从一个网站到另一个网站的连续性;否则你会知道从哪里到哪里,但不知道顺序。

with
     test_data ( Customer, Click, Website ) as (
       select 'john'  , 1, 'facebook'      from dual union all
       select 'john'  , 2, 'microsoft'     from dual union all
       select 'john'  , 3, 'facebook'      from dual union all
       select 'steven', 1, 'apple'         from dual union all
       select 'steven', 2, 'Whosebug' from dual union all
       select 'steven', 3, 'cnn'           from dual
     )
-- end of test data; the SQL query begins below this line
select *
from (
       select customer, 
              row_number() over (partition by customer order by click) as ord, 
              website as origin_website,
              lead(website) over (partition by customer order by click) as landing_website
       from   test_data
     )
where landing_website is not null
order by customer, ord
;

CUSTOMER      ORD ORIGIN_WEBSITE LANDING_WEBSITE
--------- ------- -------------- ---------------
john            1 facebook       microsoft
john            2 microsoft      facebook
steven          1 apple          Whosebug
steven          2 Whosebug  cnn

4 rows selected.