如何使用 SQL 创建矩阵

gre*_*ner 5 sql matrix sql-server-2008

使用这样的地理数据记录:

START                  |  END

CITY1    |   STATE1    |   CITY2    |  STATE2
----------------------------------------------
New York |    NY       |  Boston    |   MA
Newark   |    NJ       |  Albany    |   NY
Cleveland|    OH       |  Cambridge |   MA
Run Code Online (Sandbox Code Playgroud)

我想输出这样的东西,它计算显示为矩阵的 START/END 配对:

   |  MA  |  NJ  |  NY  |  OH
------------------------------
MA |  0   |  0   |  1   |  0
NJ |  0   |  0   |  1   |  0
NY |  1   |  0   |  0   |  0
OH |  1   |  0   |  0   |  0
Run Code Online (Sandbox Code Playgroud)

我可以看到如何GROUP BY以及COUNT将如何找到数据,但我不知道如何显示为矩阵。有没有人有任何想法?

Fli*_*mzy 4

这似乎可以解决问题,在 PostgreSQL 9.1 上进行了测试。它几乎肯定需要针对 SQL Server 进行调整(任何人都可以随意更新我的答案)。

SELECT start AS state,
    SUM((dest = 'MA')::INT) AS MA,
    SUM((dest = 'NJ')::INT) AS NJ,
    SUM((dest = 'NY')::INT) AS NY,
    SUM((dest = 'OH')::INT) AS OH
FROM (
    SELECT state1 AS start, state2 AS dest
        FROM routes
    UNION ALL
    SELECT state2 AS start, state1 AS dest
        FROM routes
) AS s
GROUP BY start
ORDER BY start;
Run Code Online (Sandbox Code Playgroud)

但请注意,我的输出与您的输出略有不同 - 我不确定这是因为您的示例输出错误,还是因为我误解了您的要求:

 state | ma | nj | ny | oh 
-------+----+----+----+----
 MA    |  0 |  0 |  1 |  1
 NJ    |  0 |  0 |  1 |  0
 NY    |  1 |  1 |  0 |  0
 OH    |  1 |  0 |  0 |  0
(4 rows)
Run Code Online (Sandbox Code Playgroud)

此查询的工作原理是查询表两次,一次查询 state1 -> state2 路由,第二次查询 state2 -> state1 路由,然后将它们用 联接在一起UNION ALL

然后,对于每个目标状态,它都会针对该行的原始状态运行SUM()

该策略应该很容易适应任何 RDBMS。

  • 谢谢。这有效。在 SQL 中:`SUM(CASE WHEN dest = 'MA' THEN 1 ELSE 0 END) AS MA`。不过,有没有办法避免编写每个“SUM”,否则有 50 行? (2认同)