|
|
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 пишу
Код:GROUP BY ( d.date >= DATE ), t.name
то выводит сначала те, которые хоть раз запланированы в будущем, а потом те, которые хотя бы раз были в прошлом
Голову уже сломал ...
|
|
|
10.03.2010, 12:22
|
|
Гость
Гость
|
Кажется я решил эту задачку ... методом научного тыка ;)
Если кому интересно (может пригодиться):
загвоздка была в том, что нужно было с одной стороны ограничить выборку дат во второй таблице, но если мы делали это во WHERE
то тем самым ограничивали вывод событий из первой таблицы только теми, которые запланированы в будущем. А нужно было вывести все, в т.ч. и те, которые были запланированы и уже прошли + которые вообще не были ни разу запланиованы. Т.е. с другой стороны использовать 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
|