如何编写正确的查询来加入所有这些表而没有重复?

Sha*_*aun 5 mysql postgresql sql-server-2005 sql-server-2008

假设我有四个表:

TABLE:    players
COLUMNS:  id, first_name, last_name

TABLE:    passing_stats
COLUMNS:  id, year, passing_yards (several other passing columns)

TABLE:    rushing_stats
COLUMNS:  id, year, rushing_yards (several other rushing columns)

TABLE:    receiving_stats
COLUMNS:  id, year, receiving_yards (several other receiving columns)
Run Code Online (Sandbox Code Playgroud)

假设 Michael Vick 的 id 为 100。我想得到他的全名和他每年的所有统计数据(传球、冲球和接球)。

我不想要任何重复,这意味着 2011 年的快速统计数据应该与 2011 年的传递统计数据出现在同一行。

编写此查询的最优雅方式是什么?谢谢。

ype*_*eᵀᴹ 6

以下将在 Postgres 中工作。在这里测试:SQL-Fiddle, postgres-test。SQL-Server 没有,NATURAL JOIN而 MySQL 有NATURAL但没有FULL连接:

SELECT
    id,
    first_name,
    last_name,
    year,
    passing_yards,
    rushing_yards,
    receiving_yards
  FROM 
      players p 
    NATURAL LEFT JOIN 
      ( passing_stats pas
      NATURAL FULL JOIN 
        rushing_stats rus
      NATURAL FULL JOIN 
        receiving_stats rec 
      )
Run Code Online (Sandbox Code Playgroud)

  • @Erwin:但是如果表中还有任何其他两列具有相同名称,它就会中断。 (2认同)

kgr*_*ttn 3

您没有提供 DDL 和数据来进行设置,因此尚未经过测试,但这些内容应该可以在 PostgreSQL 下工作。我认为这基本上符合标准,因此我希望它可以在其他产品上运行,而几乎不需要任何改变。

WITH x(id) AS (SELECT 100),
     y(year) AS (
  SELECT year FROM passing_stats t1 JOIN x ON t1.id = x.id
  UNION
  SELECT year FROM rushing_stats r1 JOIN x ON r1.id = x.id
  UNION
  SELECT year FROM receiving_stats c1 JOIN x ON c1.id = x.id)
SELECT
    p.first_name,
    p.last_name,
    y.year,
    t.passing_yards,
    r.rushing_yards,
    c.receiving_yards
  FROM x
  JOIN y ON TRUE
  JOIN players p ON p.id = x.id
  LEFT JOIN passing_stats t ON t.id = x.id AND t.year = y.year
  LEFT JOIN rushing_stats r ON r.id = x.id AND r.year = y.year
  LEFT JOIN receiving_stats c ON c.id = x.id AND c.year = y.year;
Run Code Online (Sandbox Code Playgroud)