В MySQL есть достаточное количество встроенных функций и фич, которые упрощают код. К сожалению, не все программисты знают об этом и используют свои «велосипеды». читать дальше →

SQL_CALC_FOUND_ROWS

Любой web-программист сталкивался с постраничным выводом информации. Например, в таблице лежит 1000 новостей и нужно выводить их по 10 штук на странице, а внизу вывести листалку страниц.
Программист пишет 2 запроса:

1) SELECT * FROM news WHERE activity=1 LIMIT 0, 10 // выборка записей
2) SELECT COUNT(*) FROM news WHERE activity=1// узнаем кол-во всех новостей

Второй запрос нужен для вывода листалки. Однако в MySQL есть достаточно удобная возможность объединения этих двух запросов в один. подробнее про SQL_CALC_FOUND_ROWS

SELECT DISTINCT B.TYPE_SID, B.ID BANNER_ID, B.WEIGHT BANNER_WEIGHT,
B.SHOWS_FOR_VISITOR, B.FIX_CLICK, B.FIX_SHOW, B.KEYWORDS BANNER_KEYWORDS,
C.ID CONTRACT_ID, C.WEIGHT CONTRACT_WEIGHT, C.KEYWORDS CONTRACT_KEYWORDS
FROM b_adv_type T
INNER JOIN b_adv_banner B ON ( B.ACTIVE='Y' and B.TYPE_SID = T.SID
and B.STATUS_SID = 'PUBLISHED'
and (B.FOR_NEW_GUEST is null or B.FOR_NEW_GUEST='N')
and (ifnull(B.MAX_SHOW_COUNT,0)>ifnull(B.SHOW_COUNT,0)
or ifnull(B.MAX_SHOW_COUNT,0)=0) and (ifnull(B.MAX_CLICK_COUNT,0)>ifnull(B.CLICK_COUNT,0)
or ifnull(B.MAX_CLICK_COUNT,0)=0) and (ifnull(B.MAX_VISITOR_COUNT,0)>ifnull(B.VISITOR_COUNT,0)
or ifnull(B.MAX_VISITOR_COUNT,0)=0) and (B.DATE_SHOW_FROM<=now() or B.DATE_SHOW_
FROM is null or length(B.DATE_SHOW_FROM)<=0) and (B.DATE_SHOW_TO>=now()
or B.DATE_SHOW_TO is null or length(B.DATE_SHOW_TO)<=0))
INNER JOIN b_adv_banner_2_site BS ON ( BS.BANNER_ID = B.ID and BS.SITE_ID = 'ru')
INNER JOIN b_adv_contract C ON ( C.ID = B.CONTRACT_ID and C.ACTIVE='Y'
and (ifnull(C.MAX_SHOW_COUNT,0)>ifnull(C.SHOW_COUNT,0)
or ifnull(C.MAX_SHOW_COUNT,0)=0) and (ifnull(C.MAX_CLICK_COUNT,0)>ifnull(C.CLICK_COUNT,0)
or ifnull(C.MAX_CLICK_COUNT,0)=0)  and (ifnull(C.MAX_VISITOR_COUNT,0)>ifnull(C.VISITOR_COUNT,0)
or ifnull(C.MAX_VISITOR_COUNT,0)=0) and (C.DATE_SHOW_FROM<=now() or C.DATE_SHOW_
FROM is null or length(C.DATE_SHOW_FROM)<=0) and (C.DATE_SHOW_TO>=now()
or C.DATE_SHOW_TO is null or length(C.DATE_SHOW_TO)<=0))
INNER JOIN b_adv_contract_2_site CS ON ( CS.CONTRACT_ID = B.CONTRACT_ID and CS.SITE_ID = 'ru')
INNER JOIN b_adv_contract_2_type CT ON ( CT.CONTRACT_ID = C.ID
and (CT.TYPE_SID = 'ALL' or CT.TYPE_SID = T.SID))
INNER JOIN b_adv_banner_2_weekday BW ON ( BW.BANNER_ID = B.ID
and BW.C_WEEKDAY='SUNDAY' and BW.C_HOUR = '11')
INNER JOIN b_adv_contract_2_weekday CW ON ( CW.CONTRACT_ID = C.ID
and CW.C_WEEKDAY='SUNDAY' and CW.C_HOUR = '11')
LEFT JOIN b_adv_banner_2_group UG1 ON ( (UG1.BANNER_ID = B.ID and UG1.GROUP_ID in (2,1,21)) )
LEFT JOIN b_adv_banner_2_page BP1 ON ( BP1.BANNER_ID = B.ID and BP1.SHOW_ON_PAGE='Y')
LEFT JOIN b_adv_banner_2_page BP2 ON ( BP2.BANNER_ID = B.ID and BP2.SHOW_ON_PAGE='N'
and '/e-store/books/index.php?SECTION_ID=145' like concat(BP2.PAGE, '%'))
LEFT JOIN b_adv_contract_2_page CP1 ON ( CP1.CONTRACT_ID = C.ID and CP1.SHOW_ON_PAGE='Y')
LEFT JOIN b_adv_contract_2_page CP2 ON ( CP2.CONTRACT_ID = C.ID and CP2.SHOW_ON_PAGE='N'
and '/e-store/books/index.php?SECTION_ID=145' like concat(CP2.PAGE, '%'))
LEFT JOIN b_adv_banner_2_stat_adv BA ON BA.BANNER_ID = B.ID
LEFT JOIN b_adv_banner_2_country BC ON BC.BANNER_ID = B.ID WHERE T.ACTIVE = 'Y'
and BP2.ID is null and CP2.ID is null
and (BP1.ID is null or '/e-store/books/index.php?SECTION_ID=145' like concat(BP1.PAGE, '%'))
and (CP1.ID is null or '/e-store/books/index.php?SECTION_ID=145' like concat(CP1.PAGE, '%'))
and (BA.STAT_ADV_ID is null or BA.STAT_ADV_ID='0')
and (BC.COUNTRY_ID is null or BC.COUNTRY_ID='N0')
and ( (B.SHOW_USER_GROUP = 'Y' and UG1.GROUP_ID is not null)
or (B.SHOW_USER_GROUP <> 'Y' and UG1.GROUP_ID is null))
ORDER BY B.TYPE_SID desc, C.ID desc

У Битрикса одна из лучших админок, но внутри полный бардак. Как это работает на больших таблицах?
Например, не понятно зачем делать потенциально числовые поля строковыми: CP1.SHOW_ON_PAGE='Y'

NULL означает отсутствие, неизвестность информации. Значение NULL не является значением в полном смысле слова: по определению оно означает отсутствие значения и не принадлежит ни одному типу данных. Поэтому NULL не равно ни логическому значению FALSE, ни пустой строке, ни нулю. При сравнении NULL с любым значением будет получен результат NULL, а не FALSE и не 0. Более того, NULL не равно NULL! Довольно часто программисты избегают null-значений и для нулевых полей в базе выставляют значения по умолчанию типа 0, '' (пустая строка). Во-первых, это неправильно с точки зрения семантики: 0 все-таки означает наличие информации. Во-вторых, использование подобных дефолтных значений может привести к ошибкам. Приведу пример

sql-инъекции, комиксы

Многие предприятия по разному стремятся уйти от налогов или сократить их до минимума. Для этого используют черную/двойную бухгалтерию и прочие противозаконные методы. Однако один предприимчивый деятель из Норвегии нашел изящный и остроумный ход, для того чтобы свеcти налоги к 0. В 1998 году он зарегистрировал предприятие, которое назвал ';UPDATE TAXRATE SET RATE = 0 WHERE NAME = 'EDVIN SYSE'.

sql-инъекции, налоги

Лучшее, что я смог найти. По России 2500 городов. Страны не все (не хватает Эль-Сальвадор, Эритрея, Фарерские острова и подобных малоизвестных стран, которые по сути являются мусором). читать дальше →

Задача: выбрать 5 случайных активных пользователей из таблицы user
Решение:
SELECT userid, user_name FROM user WHERE activity=1 ORDER BY RAND() LIMIT 5

ORDER BY RAND() - удобная конструкция для выборки случайных записей из таблицы. Она не очень быстрая, но удобная в случае выборки более одной случайной записи, и для небольших таблиц то, что доктор прописал. Для таблицы 20 000 записей вышеприведенный запрос занимает 0.02 с.

Вот такой интересный способ выбора случайной записи встречается иногда :-)

$res = mysql_query(‘SELECT userid, user_name FROM user WHERE activity=1’);
$j = rand(1,mysql_num_rows($res));
$i=1;
while($row=mysql_fetch_array($res)){
    if($i==$j){
        break;
    }
    $i++;
}

учебник по SQL Отличный учебник по SQL, написанный специально для тех, кто будет использовать SQL в процессе работы. Даже если это ваш первый опыт с базами данных, эта книга очень быстро научит вас свободно работать с реальным SQL, использовать простые запросы, а также снабдит вас ясными понятиями об автоматизированном управлении базой данных. Предоставит вам обучающие программы, чтобы, овладевая командами SQL шаг за шагом, помочь вам узнать, как извлекать и обрабатывать информацию, содержащуюся в таблицах данных.
Скачать Мартин Грубер. Понимание SQL (0.6 Mb, формат html)

источник неизвестен

Приходит кандидат, у которого в резюме написано «английский базовый, немецкий базовый»
Наивно предполагая, что базовые знания языка предполагают как минимум понимание простых фраз, во время беседы с кандидатом переключаюсь на английский:
— «Unfortunately I can't verify your German, but could you really understand English?»
— Я не понимаю иностранных языков...
— Ничего страшного. Программист должен уметь главным образом читать и понимать. Давайте абзац из книжки переведем...
— Я не читаю по-английски.
— А что означают слова «английский базовый» в Вашем резюме?
— Я знаю три слова: insert, update и delete. И мне их хватает.
И тут из-за монитора высовывается сотрудник с примерно втрое меньшим окладом, чем хочет данный кандидат, и спрашивает: «А как же select?!»