Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Объединение таблиц
Форумы портала PHP.SU » PHP » SQL и Архитектура БД » Объединение таблиц

Страниц (1): [1]
 

1. Мелкий - 30 Июля, 2009 - 12:21:03 - перейти к сообщению
Как 2 таблицы связать в одну, учитывая отсутствующие в другой таблице строки?

Например, есть 2 таблички:
PHP:
скопировать код в буфер обмена
  1. mysql> select * from raspis;
  2. +-----+------+----------+
  3. | day | para | namepara |
  4. +-----+------+----------+
  5. |  1  |   1  | abc      |
  6. |  1  |   2  | abc      |
  7. |  2  |   2  | abc      |
  8. |  2  |   1  | abc      |
  9. |  5  |   1  | abc      |
  10. +-----+------+----------+
  11.  
  12. mysql> select * from event;
  13. +-----+------+-------+
  14. | day | para | event |
  15. +-----+------+-------+
  16. |  5  |   1  | event |
  17. |  4  |   3  | event |
  18. |  2  |   3  | event |
  19. |  2  |   2  | event |
  20. +-----+------+-------+


При связывании получаем такое:
PHP:
скопировать код в буфер обмена
  1. mysql> select * from raspis,event where raspis.day=event.day and raspis.para=event.para;
  2. +-----+------+----------+-----+------+-------+
  3. | day | para | namepara | day | para | event |
  4. +-----+------+----------+-----+------+-------+
  5. |  5  |   1  | abc      |  5  |   1  | event |
  6. |  2  |   2  | abc      |  2  |   2  | event |
  7. +-----+------+----------+-----+------+-------+


А как получить:
PHP:
скопировать код в буфер обмена
  1. +-----+------+----------+-------+
  2. | day | para | namepara | event |
  3. +-----+------+----------+-------+
  4. |  1  |   1  | abc      | Null  |
  5. |  1  |   2  | abc      | Null  |
  6. |  2  |   1  | abc      | Null  |
  7. |  2  |   2  | abc      | event |
  8. |  2  |   3  | Null     | event |
  9. |  4  |   3  | Null     | event |
  10. |  5  |   1  | abc      | event |
  11. +-----+------+----------+-------+
2. Viper - 30 Июля, 2009 - 13:32:18 - перейти к сообщению
SELECT a.*, b.*
FROM raspis AS a
RIGHT JOIN event AS b ON a.day = b.day
учтите что условие ON используется в обязательном порядке. у вас должна быть связь какая-то по какому условию присоединять данные из второй таблицы к первой.
3. Мелкий - 30 Июля, 2009 - 14:21:59 - перейти к сообщению
Не то, так же как и Left Join - теряем записи, находящиеся только в таблице raspis или event для Right и Left соответветственно.
PHP:
скопировать код в буфер обмена
  1. mysql> select a.*, b.* from raspis as a left join event as b on (a.day = b.day and a.para=b.para);
  2. +-----+------+----------+------+------+-------+
  3. | day | para | namepara | day  | para | event |
  4. +-----+------+----------+------+------+-------+
  5. |   1 |    1 | abc      | NULL | NULL | NULL  |
  6. |   1 |    2 | abc      | NULL | NULL | NULL  |
  7. |   2 |    2 | abc      |    2 |    2 | event |
  8. |   2 |    1 | abc      | NULL | NULL | NULL  |
  9. |   5 |    1 | abc      |    5 |    1 | event |
  10. +-----+------+----------+------+------+-------+
  11. 5 rows in set (0.00 sec)
  12.  


PHP:
скопировать код в буфер обмена
  1. mysql> select a.*, b.* from raspis as a RIGHT join event as b on (a.day = b.day and a.para=b.para);
  2. +------+------+----------+-----+------+-------+
  3. | day  | para | namepara | day | para | event |
  4. +------+------+----------+-----+------+-------+
  5. |    5 |    1 | abc      |   5 |    1 | event |
  6. | NULL | NULL | NULL     |   4 |    3 | event |
  7. | NULL | NULL | NULL     |   2 |    3 | event |
  8. |    2 |    2 | abc      |   2 |    2 | event |
  9. +------+------+----------+-----+------+-------+
  10. 4 rows in set (0.00 sec)
  11.  
4. Viper - 30 Июля, 2009 - 15:03:46 - перейти к сообщению
странно. замените RIGHT JOIN на LEFT OUTER JOIN
в этом случае вы точно получите все записи.
5. Мелкий - 30 Июля, 2009 - 15:09:53 - перейти к сообщению
ничего не изменилось по сравнению с Left Join, те же 5 строк.

PS: сервер MySQL 5.0.51, на Debian Lenny.
6. EuGen - 30 Июля, 2009 - 15:23:48 - перейти к сообщению
Сейчас в голову ничего лучше, чем:
PHP:
скопировать код в буфер обмена
  1.  
  2. mysql> SELECT rapsis.*, event.* FROM rapsis LEFT JOIN event ON rapsis.`day`=event.`day` AND rapsis.para=event.para UNION DISTINCT SELECT rapsis.*, event.* FROM rapsis RIGHT JOIN event ON rapsis.`day`=event.`day` AND rapsis.para=event.para;
  3. +------+------+----------+------+------+-------+
  4. | day  | para | namepara | day  | para | event |
  5. +------+------+----------+------+------+-------+
  6. |    1 |    1 | abc      | NULL | NULL | NULL  |
  7. |    1 |    2 | abc      | NULL | NULL | NULL  |
  8. |    2 |    2 | abc      |    2 |    2 | event |
  9. |    2 |    1 | abc      | NULL | NULL | NULL  |
  10. |    5 |    1 | abc      |    5 |    1 | event |
  11. | NULL | NULL | NULL     |    4 |    3 | event |
  12. | NULL | NULL | NULL     |    2 |    3 | event |
  13. +------+------+----------+------+------+-------+
  14. 7 rows in set (0.00 sec)
  15.  

не пришло. Однако это "быстрое решение" - не самое лучшее. Так как во-первых, будет 2 соединения, и во-вторых, объединение с отбором по уникальности строк - весьма скверная вещь (из-за сортировки всех строк).
Может, что-то придумаю позже.
7. Мелкий - 30 Июля, 2009 - 16:09:14 - перейти к сообщению
Да, не самый оптимальный вариант...

Может структуру БД изменить как-то? Мне нужна результирующая таблица-еженедельник (до 7 дней и до 7 пар), которая по определённой дате и номеру пары выводит событие, а если события нет - то пару.
8. EuGen - 30 Июля, 2009 - 16:13:21 - перейти к сообщению
Так у Вас таблица всего 7 строк максимум? Тогда можете не бояться, при таких объемах даже DEPENDED SUBQUERY "пролетит" за 0.00 сек.
По поводу структуры БД - возможно, верная мысль, только тогда изложите задачу от и до полностью.
9. Мелкий - 30 Июля, 2009 - 17:04:24 - перейти к сообщению
EuGen пишет:
Так у Вас таблица всего 7 строк максимум? Тогда можете не бояться, при таких объемах даже DEPENDED SUBQUERY "пролетит" за 0.00 сек.

максимум 108 строк - день недели, до 7 пар в день, каждая из которых может быть по числителю или по знаменателю (числитель/знаменатель я опустил пока что просто). Среднее - около 30-40 строк наверное будет.

PS: да и тут скорее академический интерес, как это лучше реализовать... Посещаемость ожидаю запросов 150-200 в прыжке в сутки...


EuGen пишет:
По поводу структуры БД - возможно, верная мысль, только тогда изложите задачу от и до полностью.

Есть Идея реализовать расписание занятий студентов:
1) Для самого расписания нужно учитывать день недели, номер пары, ключ числитель/знаменатель и собственно название пары.
2) Хочется, чтобы можно было отмечать текущие изменения расписания - например "такого-то числа такой-то пары не будет" или "будет замена пары на такую-то".
Для этого как минимум хватит номера пары и даты

 

Powered by ExBB FM 1.0 RC1