[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Как лучше оформлять SQL-запросы?
DiamondeX
Только начал работать с PHP & MySQL. Нашел у IRBIS такую рекоммендацию:
//6. Не писать переменные в двойных кавычках и фигурных скобках, а использовать конкатенацию. 
//По возможности, использовать апострофы, а не двойные кавычки
//Не так:

echo "<a href='$page' >Ссылка</a>";
//а так:
echo '<a href="'. $page .'" >Ссылка</a>';


Насчет использования конкатенации понятно, а что касается апострофов, то SQL-запрос получается лучше было бы оформлять так:
$sql = 'INSERT INTO `Accounts` (`Date`, `Mail`, `Pass`) '
.'VALUES ( NOW(), \''.$mail.'\', \''.$pass.'\')';

Но обилие сочетаний символов ' и / мне не очень нравится.
С другой стороны следующий вариант намного симпатичней, хотя вроде как должен исполняться медленнее:
$sql = "INSERT INTO `Accounts` (`Date`, `Mail`, `Pass`) "
."VALUES ( NOW(), '".$mail."', '".$pass."')";

Настолько ли существенно симпатичный вариант проигрывает первому по времени, что лучше использовать первый, или же большой разницы нет?



Спустя 3 минуты, 56 секунд (9.08.2010 - 14:15) Michael написал(а):
конечно второй вариант. Там нет подстановок, разница в скорости - это больше теория. Надо делать как удобней.

Спустя 2 часа, 51 минута, 1 секунда (9.08.2010 - 17:06) uMnepaTop написал(а):
А лучше и быстрее третий вариант tongue.gif
echo '<a href="'.$page.'">Ссылка</a>';
$sql = mysql_query("INSERT INTO `accounts` (date, mail, pass) VALUES (NOW(), '{$mail}', '{$pass}')");

Спустя 1 час, 19 минут, 54 секунды (9.08.2010 - 18:26) Ice написал(а):
Цитата (uMnepaTop @ 9.08.2010 - 18:06)
А лучше и быстрее третий вариант 

Это в том случае когда запросы детсадовские

Спустя 1 час, 6 минут, 39 секунд (9.08.2010 - 19:33) uMnepaTop написал(а):
Цитата
Это в том случае когда запросы детсадовские

К чему выежнулся?) rolleyes.gif

Он совсем начинающий, умные запросы (НЕдетсадовские), ему пока что не нужны ph34r.gif

Спустя 19 минут, 27 секунд (9.08.2010 - 19:52) Ice написал(а):
так и наставляй его смолоду на говнистый путь

Спустя 6 минут, 33 секунды (9.08.2010 - 19:59) uMnepaTop написал(а):
Чем он говнистый))) blink.gif
Помойму норм все rolleyes.gif

Спустя 3 минуты, 13 секунд (9.08.2010 - 20:02) twin написал(а):
Фигурные скобки подсвечиваются далеко всеми редакторами. По этому читабельности точно не добавляют.

Спустя 1 минута, 3 секунды (9.08.2010 - 20:03) Invis1ble написал(а):
Цитата
$sql = "INSERT INTO `Accounts` (`Date`, `Mail`, `Pass`) "
  ."VALUES ( NOW(), '".$mail."', '".$pass."')";


Вопрос: а зачем конкатенировать первую строку и вторую?

Спустя 3 минуты, 34 секунды (9.08.2010 - 20:06) uMnepaTop написал(а):
А мне нравятся фигурные скобки, блокнот - форева laugh.gif
Из программ поддерживающих подсветку кода имею только нотепад++ smile.gif

Спустя 1 минута, 20 секунд (9.08.2010 - 20:08) linker написал(а):
Самый лучший вариант
$sql = "INSERT INTO `Accounts` (`Date`, `Mail`, `Pass`) "
. "VALUES ( NOW(), '" . $mail . "', '" . $pass . "')";

uMnepaTop
Лучшее - враг хорошего.

Спустя 56 секунд (9.08.2010 - 20:09) uMnepaTop написал(а):
Цитата
Лучшее - враг хорошего.

Это точно.. wink.gif

Спустя 3 минуты, 21 секунда (9.08.2010 - 20:12) Invis1ble написал(а):
Кто нибудь! Объясните мне, зачем используется конкатенация первой и второй строки SQL-запроса?

Спустя 52 секунды (9.08.2010 - 20:13) uMnepaTop написал(а):
Кстати мне тоже интересненько, только лишние байты dry.gif
Что-то я расфлудился.. ohmy.gif Пойду, пока не наказали ph34r.gif

Спустя 41 секунда (9.08.2010 - 20:14) linker написал(а):
А чтобы запрос можно было читать нормально (разделить на функциональные и логические блоки) и плюс не скролить окно редактора, если запрос длинный.

Спустя 11 минут, 14 секунд (9.08.2010 - 20:25) Invis1ble написал(а):
linker
Цитата
А чтобы запрос можно было читать нормально (разделить на функциональные и логические блоки) и плюс не скролить окно редактора, если запрос длинный.


насчёт скрола понятно, а вот для разделения блоков разве не достаточно отступов?

Спустя 2 минуты, 26 секунд (9.08.2010 - 20:27) linker написал(а):
Invis1ble
Читай "читабельность".

Спустя 6 минут, 48 секунд (9.08.2010 - 20:34) Invis1ble написал(а):
linker приму к сведению, но имхо это лишнее

Спустя 11 минут, 11 секунд (9.08.2010 - 20:45) Ice написал(а):

$sql = "SELECT m.id mid,
s.show ms,
s.href href,
menu,
submenu
FROM a_menu m
LEFT JOIN a_submenu s ON s.wid=m.class
WHERE field='
{$some['smth']}'
ORDER BY m.ord"
;
$q = mysql_query( $sql );

всяко лучше, чем "по-императорски"

$q = mysql_query("SELECT m.id mid, s.show ms, s.href href, menu, submenu FROM a_menu m LEFT JOIN a_submenu s ON s.wid=m.class ORDER BY m.ord");

Спустя 6 минут, 53 секунды (9.08.2010 - 20:52) uMnepaTop написал(а):
А мне второй больше нравится.. Каждому свое wub.gif

Спустя 1 минута, 41 секунда (9.08.2010 - 20:54) Ice написал(а):
этот запрос не из самых больших - это тоже сад.

А вообще, по-хорошему, можно создать на сервере БД хранимую процедуру, вроде этой:

DELIMETER $$
DROP PROCEDURE IF EXISTS `a`.`select_content` $$
CREATE PROCEDURE `a`.`select_content` ()
SELECT COUNT(`comments`.comment_id) AS c,
`content`.`id` AS contid,
`title`,
`thumb`,
`file`,ip,
`downloads`
FROM `content`
LEFT JOIN(`comments`) ON `comments`.`comment_id` = `content`.id
GROUP BY `comments`.comment_id
ORDER BY `content`.`id` ASC ;
DELIMETER;

и вызвать ее уже из скрипта:

mysql_query("CALL select_content()");

Спустя 18 минут, 1 секунда (9.08.2010 - 21:12) twin написал(а):
linker
Цитата
А чтобы запрос можно было читать нормально (разделить на функциональные и логические блоки) и плюс не скролить окно редактора, если запрос длинный.


uMnepaTop
Цитата
А мне второй больше нравится.. Каждому свое

Вы оба упускаете такую серьёзную возможность - диагностирование ошибок мускула построчно. Наверное именно потому, что стараетесь вытянуть текст запроса в линеечку. А ведь mysql_error() показывает номер строки с ошибкой, если использовать переносы. Ой как сильно помогает в сложных запросах.

Спустя 23 минуты, 26 секунд (9.08.2010 - 21:35) linker написал(а):
twin
Короткие запросы, аля select * from table пишу в одну строку, сложные - как описал выше. Для дебага у меня есть phpMyAdmin, ибо вываливать в браузер через mysql_error() код SQL-запроса, для меня мягко сказать не секурно, ибо приходится работать с кодом, который находится в продакшене. Именно поэтому предпочитаю аккуратного и читабельного вида записи в коде.

Спустя 5 минут, 16 секунд (9.08.2010 - 21:41) twin написал(а):
Цитата
Для дебага у меня есть phpMyAdmin, ибо вываливать в браузер через mysql_error() код SQL-запроса, для меня мягко сказать не секурно,

А в процессе отладки?
А как же твой хваленый класс для работы с БД? Неужели там нет возможности отключить/слогировать ошибки мускула? Это помоему единственно оправданное применение ООП для работы с базой данных. Хотя я спокойно обхожусь функцией.


Спустя 8 минут, 3 секунды (9.08.2010 - 21:49) linker написал(а):
twin
У меня есть правило: "Семь раз отмерь, один раз отрежь". Прежде чем пихать SQL-запрос в код, не плохо было бы его отдебажить, т.е. посмотреть, а правильно ли он составлен, а правильные ли он данные возвращает и прочее, глупо это делать непосредственно в коде. Если таки ошибка произошла, то надо искать ее не в запросе, а где-то по коду выше 100% напортачил. А классы у меня для того, чтобы в 80% банальных случаев не заморачиваться с написанием по сути одинаковых SQL-запросов.

Спустя 10 минут, 46 секунд (9.08.2010 - 21:59) Basili4 написал(а):
Это пахнет очередным халиваром ООП vs процедурки

Спустя 2 минуты, 47 секунд (9.08.2010 - 22:02) twin написал(а):
linker
Цитата
глупо это делать непосредственно в коде

Фигню же сказал. Это так, если запрос статичен.
А если запросы формируются динамически и нужно посмотреть, как он выглядит в зависимости от работы скрипта?
Тут просто необходимо видеть текст запроса на экране. Особенно его ошибки.
Единственный для этого способ - mysql_error().

Вот, дарю, кому интересно:
Свернутый текст
/** 
* Function for inquiry to DB MySQL.
* Функция для запроса к БД MySQL.
*/

function mysqlQuery($sql, $db = '', $print = false)
{
$db = is_resource($db) ? $db : '';
$result = mysql_query($sql, $db);

if($result === false || $print)
{

$error = mysql_error();
$trace = debug_backtrace();

$head = $error ?'<b style="color:red">MySQL error: </b><br>
<b style="color:green">'
. $error .'</b><br><br>':NULL;

$error_log = date("Y-m-d h:i:s") .' '. $head .'
<b>Query: </b><br>
<pre><span style="color:#CC0000">'
. $trace[0]['args'][0] .'</pre></span><br><br>
<b>File: </b><b style="color:#660099">'
. $trace[0]['file'] .'</b><br>
<b>Line: </b><b style="color:#660099">'
. $trace[0]['line'] .'</b>';

/**
*
@TODO To clean in release
*/

//-----------------------------
die($error_log);
//-----------------------------

file_put_contents(IRB_ROOT .'log/mysql.log', strip_tags($error_log) ."\n\n". FILE_APPEND);
header("HTTP/1.1 404 Not Found");
die();
}
else
return
$result;
}

Работает как простая mysql_query().
Если третьим параметром передать true или единичку, можно увидеть текст запроса.

Это сэкономило мне столько времени на разработке, что даже сложно представить.

Basili4
Причем тут ООП? Это можно и классом реализовать, кому приспичит. Тут дело в другом - в принципах разработки. smile.gif

Спустя 3 минуты, 9 секунд (9.08.2010 - 22:05) uMnepaTop написал(а):
Уважаемые прогеры! Чего Вы тут развели? Успокойтесь.. dry.gif
twin, спасибо, попользуемся smile.gif

Спустя 4 минуты, 48 секунд (9.08.2010 - 22:10) Ice написал(а):
А мне интересно, что Коля думает, как он мыслит. Как мыслят настоящие ирбисы. Сижу читаю smile.gif

Спустя 2 минуты, 19 секунд (9.08.2010 - 22:12) uMnepaTop написал(а):
Не ругайтесь, каждый по своему кодит ведь.. =\\

Спустя 40 секунд (9.08.2010 - 22:13) Ice написал(а):
Иногда тако-о-ое увидишь... blink.gif biggrin.gif

Спустя 7 минут (9.08.2010 - 22:20) twin написал(а):
А кто ругался? biggrin.gif Спокойная беседа помоему. В спорах рождается истина.

Ice
Цитата
Иногда тако-о-ое увидишь...

покаж?

Спустя 3 минуты, 38 секунд (9.08.2010 - 22:24) linker написал(а):
twin
В правильном запросе ошибка возникнет только в случае корявых данных, а корявые данные нужно искать не запросе. Мне достаточно того, что я вижу в логах и мыльных сообщениях. В браузере никаких SQL-запросов, даже их частей быть не должно, как собственно и всяких трейсов.

Спустя 9 минут, 33 секунды (9.08.2010 - 22:33) Ice написал(а):
Цитата (twin @ 9.08.2010 - 23:20)
покаж?

я говорил о воспоминаниях smile.gif а так добро пожаловать на Говнокод.ру

Спустя 47 секунд (9.08.2010 - 22:34) twin написал(а):
linker
Цитата
В правильном запросе ошибка возникнет только в случае корявых данных, а корявые данные нужно искать не запросе.

Ну значит ты блефовал по поводу разработки сложных скриптов)))

Я видел динамически создаваемые запросы на 250 строк. Правда мой личный рекорд - 75 строчек. И формируется он из кучи частей, которые генерируются на стороне PHP. Это сложнейшие сортировки, данные берутся из разных мест. И не зная, как выглядет результирующий запрос просто невозможно отладить приложение. Это диагностирование логических ошибок, а не синтаксических.

Особенно актуально при разработке таких скриптов.
Я получаю на экране текст динамически сформированного запроса и могу спокойно сунуть его в SQL и посмотреть результат. Мне не нужно делать вывод, который зависит от результатов - PMA вполне справляется. А потом, когда результат достигнут, я оформляю уже рюшечки.

Ну да каждый сходит с ума по своему. Я просто поделился соображениями, как проще и эфективнее работать.

Спустя 4 минуты (9.08.2010 - 22:38) linker написал(а):
Именно, что каждый сходит с ума по своему, кто-то оптимизирует, а кто-то гонится за количеством строчек в SQL-запросе.
Цитата
Это диагностирование логических ошибок, а не синтаксических.
Да, но только диагностика логических ошибок PHP-кода, а не SQL.

Спустя 7 минут, 59 секунд (9.08.2010 - 22:46) twin написал(а):
А причем тут оптимизация? Я далеко не сторонник сложных запросов. И часто делаю несколько простых вместо одного сложного. Как показала практика, это зачастую бывает не только читабельнее, но и эфективнее.

Я говорю о случаях, когда невозможно сделать иначе. В статистике это часто. Данных очень много, условий сортировки еще больше. Хочешь-нехочешь, приходится формировать запрос динамически. И совсем немаленький.

Ну да ладно, чего спорить, если ты не видишь очевидного.

Спустя 11 минут, 33 секунды (9.08.2010 - 22:58) linker написал(а):
Я могу понять, когда много сложных условий выборки, но вот про условия сортировки действительно не понимаю. Да, кто спорит, вот только динамическое построение запроса не обходится без аля $Sql .= "..."; и о каких номерах строк с ошибками можно вести тут речь, исключая случаев $Sql .= "...\n"; Но это равносильно моему формату
$sql = "INSERT INTO `Accounts` (`Date`, `Mail`, `Pass`)\n"
. "VALUES ( NOW(), '" . $mail . "', '" . $pass . "')";
Не можно, конечно, и извратом заняться
$sql = "INSERT INTO 
`Accounts`
(
`Date`,
`Mail`,
`Pass`
)
VALUES
(
NOW(),
'"
. $mail . "',
'"
. $pass . "'
)"
;
Смотри сколько строк запроса, уж точно не промахнешься где ошибка.
Имхо, искать логичесткие ошибки PHP-кода в динамически построенном SQL-запросе, несколько не корректно.

Спустя 10 минут, 41 секунда (9.08.2010 - 23:08) Basili4 написал(а):
Я при построении динамического запроса в первый раз вместо его выполенния вывожу либо в браузер либо в файл затем его просто копирую исполняю на клиенте если он работает как надо исполняю его уже с помощью пыхи ни разу никаких трабл небыло о чем вы спорите я не пойму. Может молодой еще smile.gif

Спустя 16 минут, 42 секунды (9.08.2010 - 23:25) twin написал(а):
linker
Цитата
Но это равносильно моему формату

Равносильно этому формату. В прошлом собщении переноса не было.
Цитата
Не можно, конечно, и извратом заняться

Изврат по сути и то, и другое. В первом случае куча лишних символов и операций. О втором и речи нет. Я вот про такую форму:
        $res = mysqlQuery("SELECT `id`, `subtitle`, `text`,
DATE_FORMAT(`date`,'%d') AS `day`,
DATE_FORMAT(`date`,'%m') AS `month`,
DATE_FORMAT(`date`,'%Y') AS `year`
FROM `"
. IRB_DBPREFIX ."news`
WHERE `public` = 1
AND `id` = "
. (int)$GET['news']);

Кстати, тот же стиль ZEND рекомендует похожую форму записи.

Что касается сортировки...
Ну представь себе, что нужно вывести данные из нескольких таблиц. И отсортировать их в зависимости от текущих условий. Вполне правомерна такая запись:

        $res = mysqlQuery("SELECT a.`date`,  a.`text`, b.`autor`
FROM `table1` a
LEFT JOIN `table2` b ON b.`id` = a.`id_autor`
WHERE b.`date` > NOW() - INTERVAL 1 WEEK "

);

А теперь нам нужно присоединить другую таблицу. Полностью переписывать запрос? Это простенький пример.
А если он на 20 - 30 строк? И таблиц штук 10? Да подключать не по одной, а по нескольку за раз? Сколько нужно запросов...

Динамически делается так:
        $fields = ", b.`autor`";
$join = " LEFT JOIN `table2` b ON b.`id` = a.`id_autor`" ;

$res = mysqlQuery("SELECT a.`date`, a.`text` ". $fields ."
FROM `table1` a
"
. $join ."
WHERE a.`date` > NOW() - INTERVAL 1 WEEK "

);

и выбираются нужные условия.
Запрос один, но скрипт в процессе тестирования и отладки может повести себя по разному. Как узнать, что именно в данный момент мы просим у мускула?

По моей схеме все просто. Ставим третий параметр и любуемся.

Как ты выкручиваешься в такой ситуации?

Спустя 5 минут, 25 секунд (9.08.2010 - 23:30) twin написал(а):
Продолжу. Что касается ошибок. Допустим что то сбилось на стороне PHP и мускул выдал ошибку запроса. Если ты их вообще не ловишь, то даже не знаю, как тебе трудно жить. А если все вытянуто в линейку, то сложно определить, где что поломалось.

В моем случае запрос на экране видно с переносами. И мускул указывает на строку с ошибкой. Очень легко определить тот блок, который отвечает за эту часть запроса. Потому что нужно всего навсего посмотреть на номер строки в PHP. А там нужная переменная.

Не представляю вообще, как можно иначе разрабатывать сложные скрипты...

Спустя 8 часов, 23 минуты, 12 секунд (10.08.2010 - 07:54) linker написал(а):
Я же сказал, что у меня есть логи и мыльный нотификатор, мне достаточно смотреть на мой sql-запрос, чтобы понять где ошибка.
Вы говорите не про сортировку ORDER BY, а про условие WHERE, не путайтесь в понятиях.
Цитата
Запрос один, но скрипт в процессе тестирования и отладки может повести себя по разному. Как узнать, что именно в данный момент мы просим у мускула?
Считаю плохой практикой, см. комменты по тексту
$fields = ", b.`autor`";
$join = " LEFT JOIN `table2` b ON b.`id` = a.`id_autor`" ;
// здесь еще 50-100 строк кода, с генерацией SQL-запроса
// А здесь пытаемся вспомнить, что такое $fields и что такое $join

$res = mysqlQuery("SELECT a.`date`, a.`text` ". $fields ."
FROM `table1` a
"
. $join ."
WHERE a.`date` > NOW() - INTERVAL 1 WEEK "

);

Спустя 21 минута, 15 секунд (10.08.2010 - 08:15) twin написал(а):
linker
Цитата
Вы говорите не про сортировку ORDER BY, а про условие WHERE, не путайтесь в понятиях.
Я привел пример, который пришел мне на данный момент в голову. В условиях WHERE бывает гораздо больше динамики. И в ORDER BY тоже. Принцип то один.
Цитата
Считаю плохой практикой, см. комменты по тексту

Цитата
// А здесь пытаемся вспомнить, что такое $fields и что такое $join

Во. И это говорит мне поборник абстракций в ООП. Ну да ладно, не суть.

Просто заявление голословно. Я считаю плохой практикой платить за квартиру. Деньги кончаются. Но если у меня нет способов сделать иначе, я ни кому не скажу - платить за квартиру плохо.

Где хорошая практика? Где примеры?

Спустя 2 минуты, 39 секунд (10.08.2010 - 08:17) linker написал(а):
Пример из Zend'ового Programmer's Reference Guid. Coding Style.
$sql = "SELECT `id`, `name` FROM `people` "
. "WHERE `name` = 'Susan' "
. "ORDER BY `name` ASC ";

Спустя 17 минут, 28 секунд (10.08.2010 - 08:35) sergeiss написал(а):
Во всём согласен с twin'ом, особенно в следующей цитате smile.gif
Цитата (twin @ 9.08.2010 - 23:46)
Я говорю о случаях, когда невозможно сделать иначе. В статистике это часто. Данных очень много, условий сортировки еще больше. Хочешь-нехочешь, приходится формировать запрос динамически. И совсем немаленький.


Я как раз со статистикой работаю.
Данные грузятся на автомате каждый день. Есть много таблиц для разных типов данных. И для одного и того же объекта есть данные в разных таблицах.
В запросах собираются те или иные данные, в зависимости от желаний юзера (разные даты, разные объекты и т.д.).
И нередка ситуация, когда нету данных какого-то типа. Либо была ошибка при их создании (это редко), либо их просто не было вообще (это чаще встречается). Но другого типа данные при этом есть. Поэтому в запросе можем получить ошибку. Не по причите "кривого" запроса, а по причине отсутствия данных.
При этом надо обязательно "отловить" проблемных запрос и информировать юзера.

Далее. Формирование запросов тоже не простое получается. Поэтому их сначала по-любому надо в переменную записать. А потом уж выполнять. Нельзя тут иметь некий "стандартный" набор запросов. Только "на лету" можно их формировать. Если надо - могу примеры привести smile.gif
И при возникновении ошибки можно этот запрос куда-то сохранить, а потом запускать его вручную и анализировать, что же именно приводит к ошибке.

Спустя 24 минуты, 53 секунды (10.08.2010 - 09:00) twin написал(а):
Пример крайне неудачный. Он приведен тут для иллюстрации способов написания длинных строк, а не SQL запросов. В этом же примере есть такая строчка:
Цитата
$company = 'Zend' . 'Technologies';

Неужели стоит писать так же и простые строки?

Вся прелесть SQL в том, что не нужно вытягивать текст программы (а запрос, это та же программа) в одну строчку. Никому же не приходит в голову писать в одну строку PHP код. Ну если только это не обфускация.

Если ты преследуешь эту цель, я полностью с тобой соглашусь. Однако речь о читабельности.

Да впрочем разговор шел не столько о стиле, сколько о удобстве использования разных форм написания. Ты высказал свое мнение:
Цитата
Считаю плохой практикой, см. комменты по тексту
но примеров хорошей практики динамического формирования запросов не привел. Единственное, что я могу предположить - это писать по отдельному запросу на каждый возможный случай.

Это не просто моветон, это мазохизм на грани самоубийства.

Спустя 1 час, 46 минут, 37 секунд (10.08.2010 - 10:46) linker написал(а):
twin
Читай ниже комменты, по ссылке, которую ты привел.
Единого стандарта, как формировать динамически запросы, нет. Но я предпочитаю, делать это последовательно, а не нахреначить сначала кучу переменных со всевозможными кусками одного сложного запроса, а потом понатыкать их в другую готовую переменную. Последовательность помогает лучше следить за логическими ошибками PHP-кода, приводящими к ошибкам в SQL-запросах.
$Sql = "SELECT ... FROM Table";
if ($ByAuthor)
$Sql .= " INNER JOIN Author ON Id = " . $AuthorId;
if (...)
$Sql .= "...";
Спускаясь по коду, я вижу как постепенно формируется запрос.
В случае небольших приятно читать в коде именно аккуратно выполненный стайлинг
$sql = "SELECT `id`, `name` FROM `people` "
. "WHERE `name` = 'Susan' "
. "ORDER BY `name` ASC ";

Спустя 4 минуты, 26 секунд (10.08.2010 - 10:51) waldicom написал(а):
Цитата (twin @ 9.08.2010 - 22:25)
$res = mysqlQuery("SELECT a.`date`, a.`text`, b.`autor`
FROM `table1` a
LEFT JOIN `table2` b ON b.`id` = a.`id_autor`
WHERE b.`date` > NOW() - INTERVAL 1 WEEK "
);

Это плохой запрос, если работа идет со стотыщмильёнов гигабайтов данных...

Спустя 40 минут, 21 секунда (10.08.2010 - 11:31) twin написал(а):
waldicom
Да чего цепляться к запросу то... Я просто прямо тут написал первое, что пришло в голову. Понятное дело, джоин не рулит. Иногда правда никуда не деться.

linker
Цитата
Последовательность помогает лучше следить за логическими ошибками PHP-кода, приводящими к ошибкам в SQL-запросах

Ну вот. Вот и пришли к тому, что и требовалось доказать. Если запрос динамически формируется так:

$Sql = "SELECT ... FROM Table";
if ($ByAuthor)
$Sql .= " INNER JOIN Author ON Id = " . $AuthorId;
if (...)
$Sql .= "...";

то результатом будет строка. Если запрос большой, то это будет большая строка. Оооочень длинная. И для того, чтобы понять, в каком именно месте что то пошло не так, придется все равно распечатать то, что получится в итоге:
print($Sql);

Неужели ты мне будешь доказывать, что в этом
SELECT `site_id`,`date`, DATE_FORMAT(`date`, '%d.%m.%Y') AS `ddt`, DATE_FORMAT(`date`, '%Y-%m-%d') AS`dat`,u.id_user, u.login, SUM(un.ru_uniq) AS ru_uniq, SUM(un.ru_not_uniq) AS ru_not_uniq, SUM(un.ua_uniq) AS ua_uniq, SUM(un.ua_not_uniq) AS ua_not_uniq, SUM(sms_uniq) AS sms_uniq, SUM(sms_not_uniq) AS sms_not_uniq, SUM(other_sms) AS other_sms, SUM(sms_money) AS sms_money, SUM(sms_real_money) AS sms_real_money, SUM(un.ru_uniq + un.other_uniq + un.ru_not_uniq + un.other_not_uniq + un.ua_uniq + un.ua_not_uniq + un.sms_not_uniq) AS ravs, SUM(un.ru_uniq + un.ua_uniq + un.other_uniq + un.sms_uniq) AS uniq, SUM(un.traffic_back_uniq + un.traffic_back_not_uniq) AS traffic_back, sum(un.initial_sales) as initial_sales, SUM(un.rebills) AS rebills, SUM(un.reject) AS reject, SUM(un.sms_money + un.ru_money + un.other_money + un.subscr_money) AS advert_money, SUM(un.referal1_money + un.subscr_referal) AS referal_money, SUM(un.sms_real_money + un.ru_real_money + un.other_real_money + un.subscr_real_money - un.bonus) AS real_money, SUM(un.bonus) AS `bonus` FROM `table1` un LEFT JOIN `table2` u ON u.id_user = un.user_id WHERE DATE_FORMAT(un.`date`, '%Y-%m-%d') >= '2010-08-10' AND DATE_FORMAT(un.`date`, '%Y-%m-%d') <= '2010-08-10' GROUP BY un.user_id

приятнее разобираться, чем в этом:
               SELECT `site_id`,`date`, DATE_FORMAT(`date`, '%d.%m.%Y') AS `ddt`, 
DATE_FORMAT(`date`, '%Y-%m-%d') AS`dat`,u.id_user, u.login,
SUM(un.ru_uniq) AS ru_uniq,
SUM(un.ru_not_uniq) AS ru_not_uniq,
SUM(un.ua_uniq) AS ua_uniq,
SUM(un.ua_not_uniq) AS ua_not_uniq,
SUM(sms_uniq) AS sms_uniq,
SUM(sms_not_uniq) AS sms_not_uniq,
SUM(other_sms) AS other_sms,
SUM(sms_money) AS sms_money,
SUM(sms_real_money) AS sms_real_money,
SUM(un.ru_uniq + un.other_uniq + un.ru_not_uniq + un.other_not_uniq +
un.ua_uniq + un.ua_not_uniq + un.sms_not_uniq) AS ravs,
SUM(un.ru_uniq + un.ua_uniq + un.other_uniq + un.sms_uniq) AS uniq,
SUM(un.traffic_back_uniq + un.traffic_back_not_uniq) AS traffic_back,
sum(un.initial_sales) as initial_sales,
SUM(un.rebills) AS rebills,
SUM(un.reject) AS reject,
SUM(un.sms_money + un.ru_money + un.other_money + un.subscr_money) AS advert_money,
SUM(un.referal1_money + un.subscr_referal) AS referal_money,
SUM(un.sms_real_money + un.ru_real_money + un.other_real_money + un.subscr_real_money - un.bonus) AS real_money,
SUM(un.bonus) AS `bonus`
FROM `table1` un
LEFT JOIN `table2` u ON u.id_user = un.user_id
WHERE DATE_FORMAT(un.`date`, '%Y-%m-%d') >= '2010-08-10'
AND DATE_FORMAT(un.`date`, '%Y-%m-%d') <= '2010-08-10'
GROUP BY un.user_id

Я уже не говорю про дебаггинг.

И чем же интересно знать такой (как ты выразился) "стайлинг"
$sql = "SELECT `id`, `name` FROM `people` "
. "WHERE `name` = 'Susan' "
. "ORDER BY `name` ASC ";

аккуратнее такого:
$sql = "SELECT `id`, `name` FROM `people` 
WHERE `name` = 'Susan'
ORDER BY `name` ASC "
;

На сколько мне известно, избыточность кода никогда не способствовала читабельности...

Спустя 4 минуты, 58 секунд (10.08.2010 - 11:36) waldicom написал(а):
Цитата (twin @ 10.08.2010 - 10:31)
waldicom
Да чего цепляться к запросу то... Я просто прямо тут написал первое, что пришло в голову. Понятное дело, джоин не рулит. Иногда правда никуда не деться.

В принципе я хотел сказать о дрдугой проблеме, а именно об использовании NOW()...

Спустя 2 минуты, 21 секунда (10.08.2010 - 11:39) waldicom написал(а):
Цитата (twin @ 10.08.2010 - 10:31)

аккуратнее такого:

$sql = "SELECT `id`, `name` FROM `people` 
WHERE `name` = 'Susan'
ORDER BY `name` ASC "
;

попробуй закомментировать отдельные поля или отдельные клаузы where...будет не удобно

Спустя 4 минуты, 34 секунды (10.08.2010 - 11:43) twin написал(а):
Есть свои минусы, не спорю. Но то, что привел как пример linker - примитив.
На самом деле зачастую запросы формируются гораздо сложнее, и последовательностью не обойтись.

Впрочем закомментировать так:
$sql = "SELECT `id`, `name` FROM `people` "
// . "WHERE `name` = 'Susan' "
. "ORDER BY `name` ASC ";

или так:
$sql = "SELECT `id`, `name` FROM `people` 
"
// WHERE `name` = 'Susan'
" ORDER BY `name` ASC ";

не особая разница.

Спустя 4 минуты, 31 секунда (10.08.2010 - 11:48) linker написал(а):
twin
А если так было бы
$sql = "SELECT `id`, `name` FROM `people` 
// WHERE `name` = 'Susan' and
family = 'pupkin'
ORDER BY `name` ASC "
;
Собственно попробуй для начала закоментить так, а потом по своему, посмотри что получится.
Холивар короче.

Спустя 3 минуты, 11 секунд (10.08.2010 - 11:51) twin написал(а):
Слив засчитан. smile.gif

Спустя 36 секунд (10.08.2010 - 11:51) linker написал(а):
twin
Это ты про себя? Согласен.

Спустя 5 минут, 17 секунд (10.08.2010 - 11:57) twin написал(а):
Неее, я про это:
Цитата
Холивар короче.

и это: Слив засчитан.
Шутка, не бери близко к сердцу.
А как комментить, я показал чуть выше.

Спустя 54 минуты, 4 секунды (10.08.2010 - 12:51) linker написал(а):
twin
Я знаю что такое слив. Я также знаю "афтар убей себя ап стену" и прочее. Слив не засчитан, ибо холивар он и в Африке холивар, но ты можешь тешить свое самолюбие и дальше.
Я тоже привел вариант твоего метода комментировать прямо в запросе, жуткая весчь получается и читабельность прямо на высоте.

P.S. ИМХО, топик можно закрывать, все что умного могли сказать - сказали.

Спустя 48 минут, 26 секунд (10.08.2010 - 13:39) twin написал(а):
Закрывать, так закрывать.
Принципы у всех разные, если тебе важнее возможность комментровать двумя символами вместо четырех (потребуется это или нет - вопрос), чем куча лишних символов и операций в коде, да еще и абсолютно нечитаемый результат, то ладно.

Я руководствуюсь другими принципами. Пишется код один раз, а читается стопицот. И сервером и последователями. Думать о сеюсекундной выгоде в ущерб эфективности и читабельности - это не ко мне.

Самолюбие мое тут где то совершенно сбоку. Тут аргументы важнее.
На все, что я привел как плюсы, ты нашел один сомнительнейший минус и ретировался. А это значит - слив засчитан. biggrin.gif

Спустя 16 минут, 25 секунд (10.08.2010 - 13:56) glock18 написал(а):
twin
что за троллиные замашки? развели холивар, вообще я удобнее всех записываю запросы tongue.gif

Спустя 3 минуты, 40 секунд (10.08.2010 - 13:59) linker написал(а):
twin
Я просто не вижу смысла тут о чем-либо спорить. Если ты этого не понимаешь, то можешь дальше считать сливы хоть до второго пришествия.

Спустя 1 минута, 29 секунд (10.08.2010 - 14:01) DedMorozzz написал(а):
twin тренируется, перед регистрацией на ЛОРе))
Ну иль, как вариант - прониклся луркмором... user posted image

Спустя 14 минут, 14 секунд (10.08.2010 - 14:15) sergeiss написал(а):
(спешно убежал за чипсами, скоро вернусь)

Спустя 3 минуты, 13 секунд (10.08.2010 - 14:18) twin написал(а):
Да я шучу, чего вы. А на лукморе прикольные вещи написаны. biggrin.gif
Конечно же каждый пишет круче всех. Это аксиома.
Я не говорю, что мой способ идеален. Мне действительно интересно, чем руководствуются люди, которые готовы пожертвовать очевидными выгодами.
Весьма вероятно я чего то недогоняю. И если аргументы весомы, то легко пересматриваю свои взгляды.

Помнится я был абсолютно уверен, что инклюд в цикле быстрее и экономичнее, чем file_get_contents() и разбор шаблона регулярками.

Меня аккуратненько натыкали носом и я поменял свое мнение. Правда не столь кардинально, но от инклюдов ушел.

Но тут то аргументов нет. Плохо со всех сторон.

1. Конкатенация, хоть и не такая страшная, но все же операция. То есть излишний функционал.
2. На каждую строку добавляется по три лишних символа. Это избыточность.
3. Отсутствие переносов, а значит нет возможности распечатать запрос в удобоваримой форме. А если использовать символ переноса, то читабельность страдает вдвое. Ибо все, что в кавычках - SQL. А символ "\n" к синтаксису SQL не имеет отношения. Это мусор.
4. То же отсутствие переносов исключает возможность построчного диагностирования. Люди зря пыхтели, изобретая такую возможность. Оказалось это все ненужно, конкатенация рулез.

Один малюююсенький плюсик. Комментировать клаузы в запросе можно двумя символами против четырех. Но если упор делается на это, то закономерно предположить, что процесс отладки запроса все же производится на стороне PHP. А все вышеперечисленные минусы в таком случае сводят на нет этот сомнительный плюсик.

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

Спустя 23 минуты, 49 секунд (10.08.2010 - 14:42) sergeiss написал(а):
Цитата (twin @ 10.08.2010 - 15:18)
Мне действительно интересно, чем руководствуются люди, которые готовы пожертвовать очевидными выгодами.

Люди руководствуются ЛОГИКОЙ. Но логикой своей. Которая у них имеется. И живя по которой они как-то даже неплохо живут.

ОФФТОП: звоню жене из магазина, спрашиваю, какие продукты купить. Она начинает ответ со списка продуктов уже ИМЕЮЩИХСЯ в доме! Если бы я её не остановил, то она бы долго перечисляла...
Вопрос: она что, не знакома с логикой?
Ответ: знакома; только это - женская логика smile.gif

Спустя 55 минут, 21 секунда (10.08.2010 - 15:37) glock18 написал(а):
sergeiss
Все просто: она просто начала перечислять все что уже есть вслух, чтобы потом когда-нибудь закончить этот список, и вспомнить "что же еще не названо" =))

Спустя 11 минут, 1 секунда (10.08.2010 - 15:48) sergeiss написал(а):
Цитата (glock18 @ 10.08.2010 - 16:37)
sergeiss
Все просто.....

Похоже, тебе это тоже хорошо знакомо и ты тоже уже научился выделять главное biggrin.gif

Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2025 Invision Power Services, Inc.