[编辑]
我现在发现了这种方法的缺陷。当为每个位置定义一名机组成员时,它运作良好,但完全跳过没有填充一些机组人员位置的行。
这是不可取的,只是从每个船员必须有船员和司机的角度来看,但此后的其他所有位置都可能是空的。
有关如何做到这一点的任何想法?阅读起来,看起来我可能需要模拟某种完全外连接。
[原稿]
我的数据库有一个供用户使用的表(称为ign_users):
-----------------------------------
¦ user_id ¦ RealName ¦ surname ¦
-----------------------------------
¦ 1 ¦ Alpha ¦ Smith ¦
-----------------------------------
¦ 2 ¦ Bravo ¦ Jones ¦
-----------------------------------
¦ 3 ¦ Charlie ¦ Brown ¦
-----------------------------------
¦ 4 ¦ Delta ¦ White ¦
-----------------------------------
我创建了一个新表来创建工作人员(称为as_crew):
------------------------------------------------
¦ name ¦ crew_leader ¦ driver ¦ crew3 ¦ crew4 ¦
------------------------------------------------
¦ A ¦ 1 ¦ 2 ¦ 3 ¦ 4 ¦
------------------------------------------------
¦ B ¦ 2 ¦ 4 ¦ 1 ¦ 2 ¦
------------------------------------------------
我希望能够做的就是加入这两个人,以便我得到每个人的全名(即真实姓名和姓氏)。
我可以一次做一个人。例如,以下内容将返回船员领队的全名:
SELECT c.name, CONCAT(u.RealName, ' ', surname)
FROM as_crew c, ign_users u
WHERE c.crew_leader=u.user_id
但是,当我尝试将其与另一个查询结合在一起时出现错误,例如:
SELECT c.name, CONCAT(u.RealName, ' ', surname)
FROM as_crew c, ign_users u
WHERE c.crew_leader=u.user_id
JOIN
(SELECT c.name, CONCAT(u.RealName, ' ', surname)
FROM as_crew c, ign_users u
WHERE c.DRIVER=u.user_id) AS t
ON c.name=t.name
我认为这是由WHERE子句引起的,但如果我只是从SELECT语句中删除它们并将它们放在外面,我就无法弄清楚如何得到这个结果。
对于船员3和船员4(以及其他人 - 他们去船员8),我只想将船员连接成一个结果。
感谢。
答案 0 :(得分:1)
首先,我会尝试将数据标准化为每个工作人员一行。从那里开始,你加入......我在最终输出中添加了额外的列,以查看记录的来源/最终消失的位置。
如果您只想要一个特定的Crew,只需在每个“SELECT / FROM”中添加相同的“WHERE”子句,因为它分解为单独的行......正如我在{}下面评论过的那样
select
PreQuery.Name,
PreQuery.CrewPosition,
PreQuery.PersonID,
CONCAT(u.RealName, ' ', U.surname) as PersonsName
from
( select c.Name,
"Crew Leader " as CrewPosition,
c.Crew_Leader as PersonID
from as_crew c
{ SPECIFIC WHERE CLAUSE }
union
select c.Name,
"Driver " as CrewPosition,
c.Driver as PersonID
from as_crew c
{ SPECIFIC WHERE CLAUSE }
union
select c.Name,
"Crew3 " as CrewPosition,
c.Crew3 as PersonID
from as_crew c
{ SPECIFIC WHERE CLAUSE }
union
select c.Name,
"Crew4 " as CrewPosition,
c.Crew4 as PersonID
from as_crew c
{ SPECIFIC WHERE CLAUSE } ) PreQuery
JOIN ign_users u
on PreQuery.PersonID = u.User_ID
这是一个让所有人都在一行的解决方案...... 根据评论反馈进行修订。
select
c.Name,
CONCAT(CL.RealName, ' ', CL.surname) as CrewLeader,
CONCAT(dr.RealName, ' ', dr.surname) as Driver,
CONCAT( CONCAT(c3.RealName, ' ', c3.surname), ', '
CONCAT(c4.RealName, ' ', c4.surname) as OtherCrew
from
as_crew c
join ign_users CL
on c.Crew_Leader = CL.User_ID
join ign_users dr
on c.Driver = dr.User_ID
join ign_users c3
on c.Crew3 = c4.User_ID
join ign_users c4
on c.Crew4 = c4.User_ID
最后......如果给定的工作人员没有所有成员......例如只有船员和司机,但没有船员3或船员4,只需将其改为LEFT JOIN而不是常规的JOIN。
答案 1 :(得分:0)
尝试:
SELECT c1.name, CONCAT(u.RealName, ' ', surname)
FROM as_crew c1, ign_users u
JOIN
( (SELECT c.name, CONCAT(u.RealName, ' ', surname)
FROM as_crew c, ign_users u
WHERE c.DRIVER=u.user_id) AS t
ON c1.name=t.name )
WHERE c1.crew_leader=u.user_id
你还得到错误吗?
答案 2 :(得分:0)
我认为你试图在union的上下文中使用join关键字。 IE你想互相“加入”结果。
SELECT c.name, CONCAT( u.RealName, ' ', surname )
FROM as_crew c, ign_users u
WHERE c.crew_leader = u.user_id
UNION ALL
SELECT c.name, CONCAT( u.RealName, ' ', surname )
FROM as_crew c, ign_users u
WHERE c.DRIVER = u.user_id
UNION ALL
SELECT c.name, CONCAT( u.RealName, ' ', surname )
FROM as_crew c, ign_users u
WHERE c.crew3 = u.user_id
等等。
编辑:我会为驾驶员号码制作另一张表格,指向机组人员编号,因此您可以只有几个where语句,例如,如果您的机组人员规模发生变化,则无需更新所有表格结构。
Edit2: 试试这个。
SELECT c.name, GROUP_CONCAT(CONCAT( ' ',u.RealName, ' ', u.surname ))
FROM as_crew c, ign_users u
WHERE c.driver = u.user_id OR c.crew_leader = u.user_id
OR c.crew3 = u.user_id
OR c.crew4 = u.user_id
OR c.crew5 = u.user_id
OR c.crew6 = u.user_id
OR c.crew7 = u.user_id
OR c.crew8 = u.user_id
GROUP BY c.name