За последние 24 часа нас посетил 21371 программист и 1021 робот. Сейчас ищут 736 программистов ...

mySQL: Алгоритмы & Полезности

Тема в разделе "PHP и базы данных", создана пользователем Chushkin, 4 авг 2015.

  1. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Тема по SQL, подобная теме в разделе по ПХП. (специально пометил, чтобы алгоритмы были оптимальны для mySQL).
    Гуру присоединяйтесь!

    1) Задача: найти все записи в таблице 1, которых нет в таблице 2
    Код (PHP):
    1. select table1.* 
    2. from table1
    3. left join table2 on table2.id = table1.id
    4. where table2.id is null
    п.с. надеюсь все понимают, что это схема и в реальных запросах надо использовать реальные метки таблиц и полей
     
  2. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    Пример того, как можно отсортировать, к примеру, цены товара, но так, чтобы товар с ценой == 0 всегда был в конце списка (пример в песочнице):

    Код (PHP):
    1. SELECT 
    2.   *
    3. FROM 
    4.   `products`
    5. ORDER BY 
    6.    IF( `price` = 0, 1, 0 ) , `price` [ASC | DESC]
    7.  
    8. /* или с помощью CASE */
    9.  
    10. SELECT 
    11.   *
    12. FROM 
    13.   `products`
    14. ORDER BY 
    15.    CASE `price` WHEN 0 THEN 1 ELSE 0 END , `price` [ASC | DESC] 
     
  3. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    2) Дата воскресенья текущей недели
    PHP:
    1. select date(now() + interval (6 - weekday(now())) day) as sunday
     
  4. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям
    @Deonis то же, но с использованием UNION ALL (здесь скобки важны!)
    Код (PHP):
    1. /* По возрастанию */
    2. (SELECT * FROM `products` WHERE `price`<>0 ORDER BY `price` ASC)
    3.   UNION ALL
    4. (SELECT * FROM `products` WHERE `price`=0)
    http://sqlfiddle.com/#!9/792d1/6
     
  5. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    3) Вывести случайное значение поля при GROUP BY.
    Навеяно темой "Задачка про выбор случайного из группы".

    Вероятно, один из самых оптимальных вариантов - без временных таблиц и подзапросов:
    PHP:
    1. select age, SUBSTRING_INDEX(min(concat_ws('|', rand(), name)), '|', -1) rand_name
    2. from test_group_by_rand
    3. group by age
    Имена/метки на основе навеянной темы.
    Структура таблицы:
    PHP:
    1. CREATE TABLE `test_group_by_rand` (
    2.   `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    3.   `name` varchar(255) DEFAULT NULL COMMENT 'Имя',
    4.   `age` int(11) DEFAULT NULL COMMENT 'Возраст',
    5.   KEY `k_test_gr` (`age`)
    6. )
     
  6. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    artoodetoo говорил про возможность вывода связанных полей,
    при таком запросе полей таблицы:
    Код (Text):
    1. CREATE TABLE children (
    2.   `id` integer auto_increment primary key,
    3.   `name` text,
    4.   `surname` text,
    5.   `age` integer
    6. );
    7.  
    8. INSERT INTO children  (`name`, `surname`, `age`) VALUES
    9.   ('Маша', 'Фокина', 3),
    10.   ('Петя', 'Ждун', 3),
    11.   ('Саша', 'Иванов', 5),
    12.   ('Кузьма', 'Прутков', 5),
    13.   ('Фархат', 'Давлетдинов', 4),
    14.   ('Зина', 'Писькина', 7),
    15.   ('Зидан', 'Волапюк', 3),
    16.   ('Родриго', 'Санчес', 4);
    выведется Петя Фокина, а не Маша,
    а так будет правильно:
    Код (Text):
    1. SELECT y.*
    2. FROM (
    3.   SELECT SUBSTRING_INDEX(
    4.     GROUP_CONCAT(`id` ORDER BY RAND()), ',', 1) AS `id`
    5.   FROM `children`
    6.   GROUP BY `age`) AS x
    7. JOIN `children` AS y USING(`id`)
     
  7. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Если нужны доп.данные, просто включите моск. ;)

    Я думал, что тут и ежу понятно, что min(...) просто лучшая замена GROUP_CONCAT(...) или подзапросу в данной задаче. А дальше по желанию, насколько запрос будет сложным.