SQL 将多个视图合并为一个的查询

SQL Query to merge several views into one

我试图从其他 3 或 4 个视图中创建一个新视图 views/tables。

表A:

title_id homeTeam
1234 WSV
5678 SSV
7890 NULL
4321 SCC

表B:

title_id awayTeam
1234 SSV
5678 SFV
7890 NULL
4321 KFC

表 C:

title_id homeTeam
1234 SSV
5678 NULL
7890 AAB
4711 BFG

我想从这三个视图中生成一个新视图,如下所示:

title_id Teams
1234 WSV, SSV, SSV
5678 SSV, SFV, N/A
7890 N/A, N/A, AAB
4321 SCC, KFC, N/A
4711 N/A, N/A, BFG

如您所见,NULL 应该重命名为 N/A,如果其他表中不存在 id 也是如此。我想得到 DISTINCT title_id.

@DaleK 当然,我这样试过:

select tableA.title_id, ISNULL(tableA.homeTeam, 'N/A') + ',' + ISNULL(tableB.awayTeam, 'N/A') + ',' + ISNULL(tableC.homeTeam, 'N/A') as Teams from tableA, tableB, tableC;

这导致对我的表进行无休止的查询,每个表都有超过 30 万行。

接下来我尝试加入:

select tableA.title_id, ISNULL(tableA.homeTeam, 'N/A') + ',' + ISNULL(tableB.awayTeam, 'N/A') + ',' + ISNULL(tableC.homeTeam, 'N/A') as Teams from tableA FULL JOIN tableB ON tableB.title_id = tableA.title_id FULL JOIN tableC ON tableC.title_id = tableA.tile_id

但老实说,我不确定行数。

试试这个:

select
    COALESCE(a.title_id,b.title_id,c.title_id),
    CONCAT(
        ISNULL(a.homeTeam,'N/A'),
        ISNULL(b.awayTeam,'N/A'),
        ISNULL(c.homeTeam,'N/A'),
        ) 'Teams',
from TableA a
    full join TableB b on a.title_id = b.title_id
    full join TableC c on c.title_id = a.title_id
where 
    a.homeTeam is not null 
    OR b.awayTeam is not null
    OR c.homeTeam is not null
group by a.title_id

至于 DISTINCT title_id,默认情况下它应该是唯一的,因为我假设它用作每个表中的键。

您可以UNION ALL将表放在一起,然后使用字符串聚合

SELECT
  t.title_id,
  STRING_AGG(ISNULL(t.team, 'N/A'), ', ') WITHIN GROUP (ORDER BY t.ordering) AS team
FROM (
    SELECT 
      a.title_id,
      a.homeTeam AS team,
      1 AS ordering
    FROM TableA a

    UNION ALL

    SELECT 
      b.title_id,
      b.awayTeam,
      2
    FROM TableB b

    UNION ALL

    SELECT 
      c.title_id,
      c.homeTeam,
      3
    FROM TableC c
) t
GROUP BY
  t.title_id;

对于SQL Server 2016及更早版本,您必须使用FOR XML方法,而且由于您必须多次查询表,因此效率较低

WITH t AS (
    SELECT 
      a.title_id,
      a.homeTeam AS team,
      1 AS ordering
    FROM TableA a

    UNION ALL

    SELECT 
      b.title_id,
      b.awayTeam,
      2
    FROM TableB b

    UNION ALL

    SELECT 
      c.title_id,
      c.homeTeam,
      3
    FROM TableC c
)
SELECT
  tOuter.title_id,
  STUFF(tInner.team.value('text()[1]', 'nvarchar(max)'), 1, LEN(', '), '') AS team
FROM (
    SELECT DISTINCT t.title_id
    FROM t
) tOuter
CROSS APPLY (
    SELECT ', ' + ISNULL(t.team, 'N/A')
    FROM t
    WHERE t.title_id = tOuter.title_id
    ORDER BY t.ordering
    FOR XML PATH(''), TYPE
) tInner(team);

db<>fiddle