我正在使用具有如下结构的表:
ID
UserID
Team1
Team2
Team3
Team4
这是一个搞砸了的结构,我知道,重组为一对多关系中的两张桌子会更好,但这是我必须要合作的。
我需要输出一个团队列表及其关联用户。问题是我有这样的数据:
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的方法,我很遗憾。有人发现更好的方式吗?
答案 0 :(得分:0)
如果可能的话,我会考虑规范化您的数据。然后只查询视图。要获取所需的数据,请使用UNPIVOT(如果是SQL Server,则使用2008或更高版本)。
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' )
;
我在数据中添加了一个额外的测试行,以显示如何使用缺少的UserID处理Team中的行。
查询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
注意:表别名显示最终数据的来源。
<强>结果:
| Team | username |
|--------|----------|
| Aces | Joe |
| Aces | Kim |
| Aces | Skip |
| Betas | Jill |
| Betas | Zed |
| Deltas | Skip |
| Deltas | Zed |
我相信在MySQL和Oracle(或任何其他可以执行UNPIVOT行为的数据库)中也有一种方法可以做到这一点,但我现在还不知道语法。如果你坚持使用SQL 2005或更低版本,那么它可以完成,但它要复杂得多。
如果您将查询设置为SQL VIEW,则只需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>
答案 1 :(得分:0)
根据您的表格结构和您必须使用的数据,多个查询的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数据库编写的):