MySQL: объединяет с внутренними предложениями WHERE - PullRequest
0 голосов
/ 06 октября 2011

[РЕДАКТИРОВАТЬ]

Теперь я обнаружил недостаток в этом подходе.Это хорошо работает, когда для каждой позиции определен член экипажа, но полностью пропускает ряды, в которых некоторые позиции экипажа не заполнены.

Это нежелательно, только с точки зрения того, что в каждом экипаже должен быть лидер экипажа.и водитель, но любая другая позиция после этого может быть пустой.

Есть мысли о том, как это сделать?Читая, похоже, мне, возможно, придется смоделировать какое-то полное внешнее объединение.

[ORIGINAL]

В моей базе данных есть таблица для пользователей (называемая 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     ¦
------------------------------------------------

Что я хочу сделать, так это объединить их, чтобы я получил полное имя (т. Е. RealNameи фамилия) для каждого члена экипажа.

Я могу сделать это по одному человеку за раз.Например, следующее вернет полное имя лидера команды:

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 и помещаю их снаружи.

Для crew3 и crew4(и другие - они идут к команде8), я просто хочу объединить команду в один результат.

Спасибо.

Ответы [ 3 ]

1 голос
/ 06 октября 2011

Во-первых, я бы попытался нормализовать данные до одного ряда на команду. Исходя из этого, сделайте ваше объединение ... Я добавил дополнительные столбцы в окончательный вывод, чтобы увидеть, как / откуда берутся записи, которые вы в конечном итоге можете удалить.

Если вам нужен только конкретный экипаж, просто добавьте к каждому «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

Наконец ... Если у заданного экипажа НЕ все члены ... например, только лидер экипажа и водитель, но нет Crew3 или Crew4, просто измените их на LEFT JOIN вместо обычного JOIN.

0 голосов
/ 06 октября 2011

Я думаю, вы пытаетесь использовать ключевое слово join в контексте union. То есть вы хотите объединить результаты друг с другом.

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
0 голосов
/ 06 октября 2011

Попробуйте с помощью:

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

Вы все еще получаете ошибки?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...