Как LEFT JOIN присоединяет данные по условию OR

Avenus

Under Glory Yield
Как LEFT JOIN присоединяет данные по условию OR

Здравствуйте!
Не могу понять как сгруппировать данные или задать правильное условие для LEFT JOIN.
Делаю выборку ID из одной таблицы с присоединением ID из другой таблицы:
PHP:
select t1.id as t1_id,t2.id as t2_id from t1 left join t2 on t2.type='XXX' or t2.type='YYY'
Получаю на выходе оба значения:
и для t2.type='XXX' и для t2.type='YYY'
Если ставлю group by t1.id, то получаю присоединенное значение t2.id, которое было первым из них занесено в таблицу.

А необходимо, при выполнении условия приоритетным считать t2.type='XXX'.

Как это решить?
 

Mr_Max

Первый класс. Зимние каникулы ^_^
Команда форума
Т.е. пример:
1) t1.id=231, t2.id=3 при t2.type='YYY'
2) t1.id=452, t2.id=6 при t2.type='XXX'
3) t1.id=343, t2.id=15 при t2.type='XXX' (даже если в таблице t2 есть значение t2.type='YYY' для t2.id=15)
4) t1.id=777, t2.id=15 при t2.type=''
Думаете Вас кто-то понял?

-~{}~ 19.10.07 00:00:

Без "куска" реальных данных из таблицы Ваш пост не несёт особой смысловой нагрузки
 

Avenus

Under Glory Yield
"Кусок" реальных данных:

В таблице t1
PHP:
t1.id=777777
t1.id=156142
В таблице t2
PHP:
t2.id=540, t2.uid=777777, t2.type='xxx'
t2.id=251, t2.uid=777777, t2.type='yyy'
t2.id=533, t2.uid=156142, t2.type='yyy'
t2.id=167, t2.uid=156142, t2.type='zzz'
Необходимо выбрать все t1.id и для них t2.id при выполнении условия t2.type='xxx' or t2.type='yyy'

Запрос:
PHP:
select t1.id as t1_id,t2.id as t2_id from t1 left join t2 on t2.uid=t1.id and (t2.type='XXX' or t2.type='YYY')
На выходе:
t1_id=777777, t2_id=540
t1_id=777777, t2_id=251 Это лишнее
t1_id=156142, t2_id=533
Как не выводить лишнее?
 

Avenus

Under Glory Yield
Поясняю:
нужен t1.id из таблицы t1 и присоединенный t2_id из таблицы t2, в которой есть запись удовлетворяющая условию:
t2.uid=t1.id и (t2.type='XXX' или t2.type='YYY')...

Что тут непонятного?
Если условие выполняется, т.е. t2.type='XXX' или t2.type='YYY', то присоединять запись из таблицы t2, если не выполняется - не присоединять.

Изначально вопрос в теме такой: как сделать так, чтобы когда есть обе записи в таблице t2 со значениями и t2.type='XXX' и t2.type='YYY' присоединялось именна та запись, у которой t2.type='XXX', а t2.type='YYY' не присоединялась?

Т.е. почему условие OR присоединяет обе записи?

-~{}~ 19.10.07 13:49:

Автор оригинала: Mr_Max
t1_id
Если делать group by t1.id, то выводит одну запись, но по для t2.type='YYY', когда присутствуют обе t2.type='XXX' и t2.type='YYY'.

А нужно при таком раскладе выбирать именно только запись с t2.type='XXX'
 

Avenus

Under Glory Yield
Как извращаться с условиями для SELECT, когда у меня условие в JOIN?
 

Mr_Max

Первый класс. Зимние каникулы ^_^
Команда форума
Думаю всё проще.

select *, t1.id as t1_id,t2.id as t2_id from t1 left join t2 on t2.uid=t1.id and (t2.type='XXX' or t2.type='YYY') GROUP BY t1_id ORDER BY t2.type

Или
select *, t1.id as t1_id,t2.id as t2_id from t1 left join t2 on t2.uid=t1.id and (t2.type='XXX' or t2.type='YYY') WHERE t2.uid IS NOT NULL GROUP BY t1_id ORDER BY t2.type



-~{}~ 19.10.07 13:38:

mysql> select *, t1.id as t1_id,t2.id as t2_id from t1 left join t2 on t2.uid=t1.id and (t2.type='XXX' or t2.type='YYY') WHERE t2.uid IS NOT NULL GROUP BY t1_id ORDER BY type;
+--------+------+--------+------+--------+-------+
| id | id | uid | type | t1_id | t2_id |
+--------+------+--------+------+--------+-------+
| 777777 | 540 | 777777 | xxx | 777777 | 540 |
| 156142 | 167 | 156142 | xxx | 156142 | 167 |
+--------+------+--------+------+--------+-------+
2 rows in set (0.00 sec)

-~{}~ 19.10.07 13:39:

.

Единственное исключение
t2.id=167, t2.uid=156142, t2.type='zzz'
поменял
t2.id=167, t2.uid=156142, t2.type='xxx'
 

Avenus

Under Glory Yield
Правильно, при группировке group by t1.id все так и будет. Но ведь в Вашем ответе происходит обычная сортировка ORDER BY type, где XXX раньше по алфавиту чем YYY... поэтому запись и выберется с type='XXX' (XXX - это условное обозначение)

А если XXX=user, а YYY=foto :) ... надо сравнивать, а вот как...
OR выбирает обе записи...

-~{}~ 19.10.07 15:25:

Извиняюсь, если ввел в заблуждение когда не указал, что type='XXX' или type='YYY' - здесь условные обозначения: XXX и YYY (вместо них другие значения).
Какие бы значения они не имели, но если присутствуют обе записи - необходимо присоединять для type='XXX'.

-~{}~ 19.10.07 15:28:

Если писать реальные значения, то и ответы будут для реальных значений, типа сортировки и т.п. Но значения могут быть разные, не писать же их все варианты :)
 

Avenus

Under Glory Yield
Может быть для примера еще проще объяснить:
Таблица t1:
t1.id=1
Таблица t2:
t2.id=1, t2.type=YYY, t2.uid=1
t2.id=2, t2.type=XXX, t2.uid=1
т.е. в таблицу t2 запись с t2.id=2 была занесена позже, но с type=XXX
Запрос:
PHP:
select t1.id as t1_id,t2.id as t2_id from t1 left join t2 on t2.uid=t1.id and (t2.type='XXX' or t2.type='YYY')
Получаем:
t1.id | t2.id
-----------------
1 | 1
1 | 2
-----------------
Изменим запрос:
PHP:
select t1.id as t1_id,t2.id as t2_id from t1 left join t2 on t2.uid=t1.id and (t2.type='XXX' or t2.type='YYY') group by t1.id
Получаем:
t1.id | t2.id
-----------------
1 | 1
-----------------
А надо:
t1.id | t2.id
-----------------
1 | 2
-----------------
 

Avenus

Under Glory Yield
:) да нет же, формировать не надо ничего... просто вместо 'XXX', к примеру, будет 'foto':
.... вот: t2.type='foto' or t2.type='user'
 

Mr_Max

Первый класс. Зимние каникулы ^_^
Команда форума
Avenus
1. Если всего 2 варианта - поменяйте тип сортировки.

Поставьте индекс для t2.type
 

Avenus

Under Glory Yield
При любой сортировке GROUP BY выберет только запись, которая была первой занесена в таблицу, а остальные отсеет... если, конечно, группировка и сортировка не по одному полю... :)
 
Сверху