使用 ColdFusion 连接来自 SQL 查询的字段

Concatenate fields from SQL query using ColdFusion

我正在使用具有如下结构的 table:

ID
UserID
Team1
Team2
Team3
Team4

这是一个搞砸的结构,我知道,重组为一对多关系中的两个 table 会更好,但这是我必须处理的。

我需要输出团队及其相关用户的列表。问题是我有这样的数据:

User: Joe    Team1: Aces
User: Jill   Team1: Betas
User: Kim    Team2: Aces
User: Skip   Team3: Deltas
User: Zed    Team1: Betas
User: Joe    Team2: Deltas

我想输出的是这样的:

Aces: Joe
Aces: Kim
Betas: Jill
Betas: Zed
Deltas: Skip
Deltas: Joe

我目前的计划是将查询结果转换为数组(我在服务器上使用 ColdFusion 8),加入它们,然后对团队进行排序。但是,我想知道我是否缺少一种更简单的、可能面向 SQL 的方法。有人发现更好的方法吗?

如果可能的话,我会考虑规范化您的数据。然后只需查询视图。要获取所需的数据,请使用 UNPIVOT(如果 SQL 服务器,则为 2008 或更高版本)。

SQL Fiddle

MS SQL Server 2014 架构设置:

CREATE TABLE users ( 
    userid int
  , username varchar(20)
) ;

INSERT INTO users (userid, username)
VALUES (1,'Joe')
  , (2,'Jill')
  , (3,'Kim')
  , (4,'Skip')
  , (5,'Zed')
;

CREATE TABLE teams ( 
    id int identity
  , userid int
  , Team1 varchar(10)
  , Team2 varchar(10)
  , Team3 varchar(10)
  , Team4 varchar(10)
) ;

INSERT INTO teams (userid, Team1, Team2, Team3, Team4)
VALUES 
    ( 1,'Aces',null,null,null )
  , ( 2,'Betas',null,null,null )
  , ( 3,null,'Aces',null,null )
  , ( 4,'Aces',null,'Deltas',null )
  , ( 5,'Betas',null,null,'Deltas' )
  , ( 6,'Aces','Betas','Nobody','Deltas' )
;

我在数据中添加了一个额外的测试行,以展示如何处理 Team 中缺少 UserID 的行。

查询 1:

SELECT t3.Team, t3.username
FROM (
  SELECT t2.userid, t2.username, t2.Team
  FROM (
    SELECT u.userid, u.username, t.Team1, t.Team2, t.Team3, t.Team4
    FROM teams t
    LEFT OUTER JOIN users u ON t.userid = u.userid
  ) ut
  UNPIVOT
  ( Team FOR Teams IN (Team1, Team2, Team3, Team4 ) ) t2 
  WHERE t2.userid IS NOT NULL
) t3
ORDER BY Team, username

注意:table 别名显示最终数据的来源。

结果:

|   Team | username |
|--------|----------|
|   Aces |      Joe |
|   Aces |      Kim |
|   Aces |     Skip |
|  Betas |     Jill |
|  Betas |      Zed |
| Deltas |     Skip |
| Deltas |      Zed |

我相信在 MySQL 和 Oracle(或任何其他可以执行 UNPIVOT 行为的数据库)中也有一种方法可以做到这一点,但我现在不知道语法。如果您卡在 SQL 2005 或更低版本,可以完成,但要复杂得多。


如果您使查询成为 SQL 视图,您只需 cfquery 视图然后输出那些结果。

<cfquery name="foo" datasource="#myDSN#">
    SELECT Team, username
    FROM vw_teamUsers (or whatever you name it)
</cfquery>

<cfoutput query="foo">
    #Team#: #username# <br>
</cfoutput>

考虑到您的 table 结构和您必须处理的数据,多个查询的 UNION 可能是适合您的解决方案:

( SELECT Team1 as Team, UserName
FROM teamData as td1
WHERE td1.Team1 IS NOT NULL
AND td1.Team1 != '' )
UNION
( SELECT Team2 as Team, UserName
FROM teamData as td2
WHERE td2.Team2 IS NOT NULL
AND td2.Team2 != '' )
UNION
( SELECT Team3 as Team, UserName
FROM teamData as td3
WHERE td3.Team3 IS NOT NULL
AND td3.Team3 != '' )
UNION
( SELECT Team4 as Team, UserName
FROM teamData as td4
WHERE td4.Team4 IS NOT NULL
AND td4.Team4 != '' )
ORDER BY Team, UserName;

这给你:

Team    UserName
Aces    Joe
Aces    Kim
Betas   Jill
Betas   Zed
Deltas  Skip

工作 SQLFiddle 在这里进行测试(这是针对 MySQL 数据库编写的):

http://sqlfiddle.com/#!9/8e7651/30