Sql server SQL Server 2008R2从表到图形的边

Sql server SQL Server 2008R2从表到图形的边,sql-server,tsql,graph,sql-server-2008-r2,sql-graph,Sql Server,Tsql,Graph,Sql Server 2008 R2,Sql Graph,我偶然发现了一个有趣的挑战。我在SQL Server表中有以下格式/内容的数据 Date | Name ---------+--------- 1/1/2010 | John 1/1/2010 | Mark 1/1/2010 | Peter 1/1/2010 | Mia 2/4/2010 | John 2/4/2010 | Billy 我试图将该表转换为包含图形边的文件 我需要edges文件包含列和表中显示的所有组合 John | Mark John | Peter John | Mi

我偶然发现了一个有趣的挑战。我在SQL Server表中有以下格式/内容的数据

Date     | Name
---------+---------
1/1/2010 | John
1/1/2010 | Mark
1/1/2010 | Peter
1/1/2010 | Mia
2/4/2010 | John
2/4/2010 | Billy
我试图将该表转换为包含图形边的文件

我需要edges文件包含列和表中显示的所有组合

John | Mark
John | Peter
John | Mia
Mark | Mia
Mark | Peter
Peter | Mia
John | Billy
我怀疑这一部分可以通过pivot/unpivot实现,但不知道如何将pivot限制为仅两列


此外,我不知道如何确保获得所有可能的节点组合,请注意前四个“节点”需要成为六个“边”。

您可以使用
行数和“三角形连接”:

注:

要获得稳定排序,您需要添加一列,该列将指示组内具有相同日期的顺序。我使用了
Name
,但它交换了最后两行中的名称


带有
ID
列的版本:

CREATE TABLE tab(ID INT IDENTITY(1,1)
                 ,Date DATE  NOT NULL 
                 ,Name VARCHAR(6) NOT NULL);

INSERT INTO tab(Date,Name) 
VALUES ('1/1/2010','John'), ('1/1/2010','Mark'), ('1/1/2010','Peter')
      ,('1/1/2010','Mia'), ('2/4/2010','John'),('2/4/2010','Billy');

WITH cte AS
(
  SELECT *, rn = ROW_NUMBER() OVER(PARTITION BY date ORDER BY ID)
  FROM tab
)
SELECT c.Name, c2.Name
FROM cte c
JOIN cte c2
  ON c.Date = c2.Date
  AND c.rn < c2.rn;
╔═══════╦═══════╗
║ Name  ║ Name  ║
╠═══════╬═══════╣
║ John  ║ Mark  ║
║ John  ║ Mia   ║
║ John  ║ Peter ║
║ Mark  ║ Mia   ║
║ Mark  ║ Peter ║
║ Mia   ║ Peter ║      -- ORDER BY based on `Name`
║ Billy ║ John  ║      -- same here `B` before `J`
╚═══════╩═══════╝
CREATE TABLE tab(ID INT IDENTITY(1,1)
                 ,Date DATE  NOT NULL 
                 ,Name VARCHAR(6) NOT NULL);

INSERT INTO tab(Date,Name) 
VALUES ('1/1/2010','John'), ('1/1/2010','Mark'), ('1/1/2010','Peter')
      ,('1/1/2010','Mia'), ('2/4/2010','John'),('2/4/2010','Billy');

WITH cte AS
(
  SELECT *, rn = ROW_NUMBER() OVER(PARTITION BY date ORDER BY ID)
  FROM tab
)
SELECT c.Name, c2.Name
FROM cte c
JOIN cte c2
  ON c.Date = c2.Date
  AND c.rn < c2.rn;
╔═══════╦═══════╗
║ Name  ║ Name  ║
╠═══════╬═══════╣
║ John  ║ Mark  ║
║ John  ║ Peter ║
║ John  ║ Mia   ║
║ Mark  ║ Peter ║
║ Mark  ║ Mia   ║
║ Peter ║ Mia   ║
║ John  ║ Billy ║
╚═══════╩═══════╝