Елена Б.
6863 повідомлення
#14 років тому
Прошу совет профессионалов по SQL.

Есть запрос вида (код РНР):
"SELECT  * FROM ".$table." WHERE  Publish = '1' ORDER BY id DESC;"

Но не все таблицы, которые могут попасть в переменную $table имеют поле Publish.
Сейчас проверка этого поля возложена на РНР. Но хочется написать условие типа:
"SELECT  * FROM ".$table." WHERE  Publish = '1'  OR Поля Publish вообще нет ORDER BY id DESC;"

Или врогде такого
"SELECT  * FROM ".$table." 
WHERE Если такое поле есть, то Publish = '1', а если нету, то проигнорировать это условие
ORDER BY id DESC;"

Да еще так написать, чтоб ошибок не было

Другими словами, в выборку не должны попасть записи, в которых есть поле Publish == 0.

Подскажите, пожалуйста, как правильно.
Максим Ф.
3195 повідомлень
#14 років тому
В запросе вы выбираете из конкретной таблицы, где есть это поле. Там, где этого поля нет, должен быть другой запрос. С учётом того, что поле паблиш где-то есть, а где-то нет, БД ваша не соответствует критериям нормальности, это не хорошо.

Можно попробовать выборку без паблиш'а обработать средствами php: делать что-то, если result есть, и другое - если нет.
Елена Б.
6863 повідомлення
#14 років тому
Цитата ("AlekartRu"):
С учётом того, что поле паблиш где-то есть, а где-то нет, БД ваша не соответствует критериям нормальности, это не хорошо.

Приведите, пожалуйста эти критерии. Где-то сказано, что все таблицы в БД должны иметь идентичную структуру?

Цитата ("AlekartRu"):
Можно попробовать выборку без паблиш'а обработать средствами php

Так оно и работает сейчас.

Вариант один.
После выборки записи проверяются на соответствие этому условию и ненужные отметаются.
Недостаток - приходится тянуть из запроса кучу малу мусора, что не есть хорошо.

Вариант два.
Перед этим запросом анализируется структура таблицы и в зависимости от нее подставляется условие в запрос.
Недостаток - лишний запрос в базу.

Поэтому решение на стороне SQL кажется мне предпочтительным.

Если решение на SQL не найдется, то сопутствующий вопрос: какой из вариантов РНР-реализации лучше?
Нет, не так спрошу. В каких пределах будет лежать то критическое число записей, после которого лучше использовать второй вариант?
Максим Ф.
3195 повідомлень
#14 років тому
Цитата ("floppox"):
Приведите, пожалуйста этикритерии.

первое, что попалось:

Цитата ("floppox"):
Где-то сказано, что все таблицы в БД должны иметь идентичную структуру?

Если более двух таблиц имеют одно и то же поле, можно вынести это поле и связь с ним в отдельную таблицу. Нормализация называется.

И вообще, я не программист. Ждите лучше квалифицированного ответа.
Евгений Б.
5330 повідомлень
#14 років тому
Цитата ("floppox"):
Где-то сказано, что все таблицы в БД должны иметь идентичную структуру?

ни где, но в Вашем случае Вы хотите объединить в одном запросе разные таблицы.
а если таблицы вообще разные? в одной список товаров, во второй список пользователей?
Елена Б.
6863 повідомлення
#14 років тому
Ну, вообще-то я знаю, что там и как.
В переменную $table не инопланетяне значение вписывают.
Тем более, что этот фокус уже работает на нескольких сайтах, где быстродействие не критично.

Сейчас (в новом проэкте) встал вопрос о более существенной нагрузке, поэтому нужна модернизация.
Роман Беляев
16382 повідомлення
#14 років тому
Разные таблицы - разные запросы. Одним запросом выбирать из таблицы структура которой может отличаться от ожидаемой - нонсенс.
Артём К.
1157 повідомлень
#14 років тому
Цитата ("AlekartRu"):
Если более двух таблиц имеют одно и то же поле, можно вынести это поле и связь с ним в отдельную таблицу. Нормализация называется.


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

Цитата ("floppox"):
В переменную $table не инопланетяне значение вписывают.


Так вот именно. Вот в скрипте и разбираться, что за таблица и запрос формировать.
Дмитрий Засядько
87 повідомлень
#14 років тому
А может быть сделать хранимую процедуру, которая будет проверять наличие поля.
Евгений Б.
5330 повідомлень
#14 років тому
Цитата ("floppox"):
Тем более, что этот фокус уже работает на нескольких сайтах, где быстродействие не критично.

т.е. неверная структура тянется из проекта в проект и все ждет, что бы в какой нить момент навернуть все сразу.
Виктор Т.
1036 повідомлень
#14 років тому
Цитата ("floppox"):
Но хочется написать условие типа:
Код:1"SELECT  * FROM ".$table." WHERE Publish = '1'  OR Поля Publish вообще нет ORDER BY id DESC;"
Или врогде такого
Код:123"SELECT  * FROM ".$table."
WHERE Если такое поле есть, то Publish = '1', а если нету, то проигнорировать это условие
ORDER BY id DESC;"
Да еще так написать, чтоб ошибок не было

Другими словами, в выборку не должны попасть записи, в которых есть поле Publish == 0.

Подскажите, пожалуйста, как правильно.

Правильно - формировать свой запрос для каждой таблицы. Более того, это единственно верно, поскольку компилятор не пропустит выражение если в нем будет поле, которого нет в таблице
Василий С.
402 повідомлення
#14 років тому
Цитата ("floppox"):
Есть запрос вида (код РНР):
"SELECT  * FROM ".$table." WHERE  Publish = '1' ORDER BY id DESC;"

Но не все таблицы, которые могут попасть в переменную $table имеют поле Publish.

Не-не-не!
уже не правильно, если переменная $table содержит несколько таблиц, т.к. в данном запросе они никак не связанны.
Если Вы настаиваите, что выборка должна идти из нескольких таблиц, гуглите синтаксис LEFT JOIN
---
Упс... не очень внимательно прочитал вопрос.
т.е. сейчас переменная $table принимает значения названий разных таблиц. И среди этих таблиц иногда попадаются те, где нет нужного поля?
И сейчас проблема решается на уровне php, но Вы хотите перенести это на mysql?
Вряд ли получите существенный прирост производительности - оставьте лучше как есть
Елена Б.
6863 повідомлення
#14 років тому
Цитата ("tarakan_"):
т.е. сейчас переменная $table принимает значения названий разных таблиц. И среди этих таблиц иногда попадаются те, где нет нужного поля?
И сейчас проблема решается на уровне php, но Вы хотите перенести это на mysql?
Вряд ли получите существенный прирост производительности - оставьте лучше как есть

Большое спасибо. Самый толковый ответ из всех.

Критикующим господам спешу сказать, что я все-таки знаю, что и как формируется в скрипте, что и где запрашивается. Так надо, и это работает. Но всегда можно "помыть слона" немножко лучше.
Думала-думала, и решила, просто добавить поле Publish во все таблицы без разбору. Хотя до сих пор старалась не создавать ни одного хоть капельку лишнего поля, но склоняюсь к тому, что один байт даных + 7 байт названия столбца погоды не сыграют.
Денис Ш.
7132 повідомлення
#14 років тому
floppox, в любой СУБД есть системные таблицы, в которых хранятся данные о полях.

В вашем случае можно попробовать анализировать через "SHOW FULL COLUMNS FROM @table", но как вам сказали, производительность не вырастет - любая универсальность идет в ущерб производительности, т.к. требует лишних проверок
Роман Беляев
16382 повідомлення
#14 років тому
Оффтопик
Костыль на костыле и костылем погоняет
Вячеслав Кремешный
92 повідомлення
#14 років тому
На php сделайте предварительный запрос. 4-5 строк и все готово.
Елена Б.
6863 повідомлення
#14 років тому
Ой, люди. Ну почему девять из десяти никогда не читают все, что написано выше? Ведь не тридцать страниц обсуждения, можно и просмотреть...

Цитата ("frig"):
Костыль на костыле и костылем погоняет

Вам достаточно одной строки, чтоб оценить код? Вы гений!
Антон С.
1316 повідомлень
#14 років тому
Вероятно решение таково - делаем mysql функцию, которая проверяет наличие в таблице поля publish ( с помощью системных таблиц ), а потом делает запрос по ситуации)
Роман Беляев
16382 повідомлення
#14 років тому
Цитата ("floppox"):
Вам достаточно одной строки, чтоб оценить код?


Нет, не достаточно знать, что для того чтобы подогнать все под свои условия (не вполне корректные, к слову) принимается решение добавить ко всем таблицам левое поле.

Цитата ("floppox"):
Вы гений!


Спасибо, я знаю
Сергей К.
1649 повідомлень
#14 років тому
1. mysql_list_fields - список полей таблицы.
2. По результатами этой функции и стройте уже запрос.
Как то так.