Регистрация
Вход через соцсети
Восстановление пароля

Вывод списка 1 в соответствии со списком 2

Новый топик
18.02.2010, 23:52
Ответить | Цитировать
Гость
Гость

Подскажите можно ли такое сделать:

Есть два шаблона:
A. id события и Название события,
B. дата наступления события и id события из первого шаблона.

Нужно вывести единый список событий из шаблона A, но чтобы сначала шли те события, для которых существует дата наступления в шаблоне B, а затем те, для которых даты наступления нет.
Причем события в 1-й и во 2-й группе (с указанной датой и без) нужно отсортировать по Названию события.

Возможно ли это без очень хитрых обращений к БД?
19.02.2010, 13:00
Ответить | Цитировать
pe3udent
Артур Юсупов

Зарегистрирован:
2008-04-03
Сообщений: 220

Как вариант (при условии что поле ID во второй таблице уникально):

Код:
SELECT t.id, t.name, d.date, IF(d.date, 1, 0) AS flag
FROM Table1 AS t
LEFT JOIN Table2 AS d ON d.id = t.id
ORDER BY flag DESC, t.name ASC


Но нужно учесть, что "Using temporary; Using filesort" даст о себе знать при работе с большими объемами данных.
19.02.2010, 17:34
Ответить | Цитировать
Гость
Гость

Супер!!! Спасибо!

И, уж извините, еще один вопросик:
если какое-то событие запланировано несколько раз,
можно ли заставить t.name выводиться только первый раз - в первой строке, а в остальных, например, пробелом ...
23.02.2010, 18:41
Ответить | Цитировать
Гость
Гость

Раз никто не отвечает - видимо нельзя.
Пришлось вставить в вывод кусочек кода.

А подскажите тогда, можно ли часть этого запроса
" LEFT JOIN Table2 AS d ON d.id = t.id "
для перегруппировки вывода списка объектов поместить в системные настройки шаблона,
по аналогии с $query_where или $query_order
24.02.2010, 07:59
Ответить | Цитировать
pe3udent
Артур Юсупов

Зарегистрирован:
2008-04-03
Сообщений: 220

Код:
$query_join = "LEFT JOIN Table2 AS d ON d.id = t.id";
24.02.2010, 08:07
Ответить | Цитировать
pe3udent
Артур Юсупов

Зарегистрирован:
2008-04-03
Сообщений: 220

Рома писал(а):
если какое-то событие запланировано несколько раз,
можно ли заставить t.name выводиться только первый раз - в первой строке, а в остальных, например, пробелом ...


Можно сделать средствами PHP.
07.03.2010, 02:31
Ответить | Цитировать
Гость
Гость

Спасибо, очень помогли.

Осталось мне сделать последний (надеюсь) запрос, никак не могу сформулировать...

Задача прежняя - вывести из первой таблицы Table1 события, но сначала должны идти те события, которые запланированы во второй таблице, а потом те, которые не запланированы.
Но(!) сложность в том, что во второй таблице есть уже пройденные/свершившиеся события (но они в Table2 остались), но их учитывать как бы не нужно ...
Причем некоторые события могут быть запланированы несколько раз - как в прошлом, так и в будущем, а вывести их нужно только один раз, причем с ближайшей (еще не наступившей) датой.
Если делать как вы писали
Код:

SELECT t.id, t.name, d.date, IF(d.date, 1, 0) AS flag
FROM Table1 AS t
LEFT JOIN Table2 AS d ON d.id = t.id
ORDER BY flag DESC, t.name ASC

то, понятно, выводятся все-все-все: сначала запланированные (причем несколько раз - если есть несколько дат), потом незапланированные ...
Делаю такой запрос (пишу немного упрощенно, DATE - сегодняшняя дата):
Код:

SELECT t.id, t.name, d.date, IF(d.date >= DATE, 1, 0) AS flag
FROM Table1 AS t
LEFT JOIN Table2 AS d ON d.id = t.id
GROUP BY t.name
ORDER BY flag DESC, t.name ASC

то выводит все события, но те из них, которые уже были запланированы ранее (и уже прошли) и запланированы в будущем при группировке объединяются с flag = 0 (видимо потому, что прошедшие даты были запланированы первыми), хотя нужно их получить с flag = 1 и ближайшей датой в будущем.

Если дабавляю
Код:
WHERE d.date >= DATE

то, понятно, выводятся только те события, для которых есть дата в будущем.

Если вместо WHERE пишу
Код:
GROUP BY ( d.date >= DATE ), t.name

то выводит сначала те, которые хоть раз запланированы в будущем, а потом те, которые хотя бы раз были в прошлом

Голову уже сломал ...
10.03.2010, 12:22
Ответить | Цитировать
Гость
Гость

Кажется я решил эту задачку ... методом научного тыка ;)
Если кому интересно (может пригодиться):

загвоздка была в том, что нужно было с одной стороны ограничить выборку дат во второй таблице, но если мы делали это во WHERE
Код:
WHERE d.date >= DATE

то тем самым ограничивали вывод событий из первой таблицы только теми, которые запланированы в будущем. А нужно было вывести все, в т.ч. и те, которые были запланированы и уже прошли + которые вообще не были ни разу запланиованы. Т.е. с другой стороны использовать WHERE было нельзя ...

В очередной раз рассматривая синтаксис оператора SELECT, попробовал вставить это ограничение в LEFT JOIN ... ON ...
и все заработало! Получилось:
Код:

SELECT t.id, t.name, d.date, IF(d.date >= DATE, 1, 0) AS flag
FROM Table1 AS t
LEFT JOIN Table2 AS d ON (d.id = t.id) AND (d.date >= DATE)
GROUP BY t.name
ORDER BY flag DESC, t.name ASC
198 196 2010-03-10 12:22:44 9859
Описание проекта