简体   繁体   English

MySQL:使用内部WHERE子句联接

[英]MySQL: Joins with inner WHERE clauses

[EDIT] [编辑]

I have now discovered the flaw in this approach. 我现在发现了这种方法的缺陷。 It works well when there is a crew member defined for every position, but completely skips the rows where some crew positions are not filled in. 当为每个职位定义了一个工作人员时,它会很好地工作,但是完全跳过一些未填写工作人员职位的行。

This is undesirable, only from the perspective that every crew must have a crew leader and a driver, but every other position after that could be empty. 仅从每个乘务员都必须有一个乘务组长和一名驾驶员的角度来看,这是不希望的,但此后的每个其他位置都可能为空。

Any thoughts on how to do that? 关于如何做的任何想法? Reading up, it looks like I might have to simulate some sort of full outer join. 阅读后,看来我可能不得不模拟某种完全外部联接。

[ORIGINAL] [原版的]

My database has a table for users (called ign_users): 我的数据库有一个用户表(称为ign_users):

-----------------------------------
¦ user_id ¦ RealName  ¦ surname   ¦
-----------------------------------
¦ 1       ¦ Alpha     ¦ Smith     ¦
-----------------------------------
¦ 2       ¦ Bravo     ¦ Jones     ¦
-----------------------------------
¦ 3       ¦ Charlie   ¦ Brown     ¦
-----------------------------------
¦ 4       ¦ Delta     ¦ White     ¦
-----------------------------------

I have created a new table to create crews (called as_crew): 我创建了一个新表来创建工作人员(称为as_crew):

------------------------------------------------
¦ name  ¦ crew_leader ¦ driver ¦ crew3 ¦ crew4 ¦
------------------------------------------------
¦ A     ¦ 1           ¦ 2      ¦ 3     ¦ 4     ¦
------------------------------------------------
¦ B     ¦ 2           ¦ 4      ¦ 1     ¦ 2     ¦
------------------------------------------------

What I want to be able to do is join the two so that I get the full name (ie. RealName and surname) for each person on the crew. 我想要做的是将两者合而为一,以便为乘员组中的每个人获得全名(即,真实姓名和姓氏)。

I can do this one person at a time. 我一次可以做一个人。 For example, the following will return the full name of the crew leader: 例如,以下将返回组长的全名:

SELECT c.name, CONCAT(u.RealName, ' ', surname)
FROM as_crew c, ign_users u
WHERE c.crew_leader=u.user_id

However, I get errors when I try to join this together with another query, eg: 但是,当我尝试将其与另一个查询一起加入时出现错误,例如:

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

I think this is due to the WHERE clauses, but I can't figure out how to get this result if I simply remvoe them from inside the SELECT statements and put them on the outside. 我认为这是由于WHERE子句引起的,但是如果我只是从SELECT语句内部删除它们并将它们放在外面,就无法弄清楚如何获得此结果。

For crew3 and crew4 (and others - they go up to crew8), I just want to concatenate the crew together into one result. 对于乘员组3和乘员组4(以及其他人-他们升至乘员组8),我只想将乘员组连接成一个结果。

Thanks. 谢谢。

First, I would try to normalize the data to one row per crew. 首先,我会尝试将数据标准化为每个工作人员一行。 From THAT, do your join... I've added extra columns in the final output to see how/where the records come from that you can ultimately strip out. 从那开始,进行联接...我在最终输出中添加了额外的列,以查看记录的来源/来源,以便最终删除它们。

If you want only a specific Crew, Just add the same "WHERE" clause to each "SELECT/FROM" as its breaking down into individual rows... as I've commented with { } below 如果只需要特定的乘员组,只需在每个“ 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

Here's a solution to get all people on a single row... Revised per comment feedback. 这是使所有人都排成一行的解决方案...根据评论反馈进行了修订。

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

Finally... If a given crew does NOT have all members.. such as only a crew leader and driver, but no Crew3 or Crew4, just change those to LEFT JOIN instead of regular JOIN. 最后...如果给定的机组人员没有所有成员..例如仅机组人员和驾驶员,而没有Crew3或Crew4,只需将其更改为LEFT JOIN而不是常规JOIN。

Try with: 尝试:

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

Do you still get the errors? 您仍然收到错误吗?

I think you are trying to use the join keyword in the context of union. 我认为您正在尝试在并发上下文中使用join关键字。 IE you want to 'join' results to each other. 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

and so on. 等等。

Edit : I'd make another table for driver numbers pointing at crew numbers, so you can just have a couple of where statements and you don't have to update all your table structures if your crew size changes, for example. 编辑:我将为驾驶员编号制作另一个表,以指向乘员编号,因此您可以只包含几个where语句,例如,如果乘员人数发生变化,则不必更新所有表结构。

Edit2 : Try this out. 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM