За последние 24 часа нас посетили 21800 программистов и 1008 роботов. Сейчас ищут 737 программистов ...

Группировка значений

Тема в разделе "MySQL", создана пользователем AnonimS, 27 фев 2019.

  1. AnonimS

    AnonimS Новичок

    С нами с:
    8 дек 2016
    Сообщения:
    88
    Симпатии:
    9
    Добрый день! Столкнулся с задачей интересной, не могу решить. Есть таблица примерно 1000 строк, все столбцы описывать не буду, интересует только 1. Порядок вывода. По нему сортируется таблица и выводятся значения. Соответственно первая выборка э то от 1 до 10. Задача в том, что если есть 2 повторяющихся значения надо их сгруппировать и вывести случайную.
    Код (Text):
    1. а - 1
    2. к - 1
    3. б - 2
    4. с - 3
    5. д - 4
    6. п - 11
    7. йц - 11
    8. пц - 11
    9. пц - 11
    Итого надо получить что-то типа того
    Код (Text):
    1. а - 1
    2. б - 2
    3. с - 3
    4. д - 4
    5. п - 11
    6. йц - 11
    7. пц - 11
    8. пц - 11
    Еще запрос, то так
    Код (Text):
    1. к - 1
    2. б - 2
    3. с - 3
    4. д - 4
    5. п - 11
    6. йц - 11
    7. пц - 11
    8. пц - 11
    Буду благодарен хотя бы за наводку куда смотреть. Думал Union использовать, ну это не правильно, хотелось бы все в 1 запросе..
     
  2. Valick

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

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    Для начала смотри в сторону GROUP BY
     
  3. AnonimS

    AnonimS Новичок

    С нами с:
    8 дек 2016
    Сообщения:
    88
    Симпатии:
    9
    GROUP BY группирует все значения, а мне надо что-то типа условия группировки having тоже не то - это фильтр
     
  4. Babka_Gadalka

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

    С нами с:
    16 фев 2019
    Сообщения:
    162
    Симпатии:
    23
    Адрес:
    Москва, Пушкина, Избушкина, 2й этаж душечка.
    Над этим можно и поколдовать
    PHP:
    1. SELECT * FROM users WHERE login IN
    2. (SELECT login FROM users
    3. GROUP BY login HAVING COUNT(login)>1)
     
  5. Valick

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

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    Бабка гадала гадала да не угадала
    @AnonimS, ты спорить пришёл или запрос писать? Напиши запрос с группировкой
    Не ну если не хочешь напрягаться, могу готовый запрос рублей за 300 продать
     
  6. Babka_Gadalka

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

    С нами с:
    16 фев 2019
    Сообщения:
    162
    Симпатии:
    23
    Адрес:
    Москва, Пушкина, Избушкина, 2й этаж душечка.
  7. Valick

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

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @Babka_Gadalka, ни с запросом ни с яндухом не угадала, долго тебе до пенсии то?
     
  8. AnonimS

    AnonimS Новичок

    С нами с:
    8 дек 2016
    Сообщения:
    88
    Симпатии:
    9
    Спасибо за идею, помогло. Основной запрос не трогал, сделал во FROM подзапрос, чтобы выборка уже была из "готовых строк". Однако криво как-то получается я для каждой из 10 строк делаю запрос и вытаскиваю случайную строку. по сути 10 запросов со схожей логикой, задача которой вытащить 1 случайную строчку, если их более 1..
     
  9. Valick

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

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    вообще никуда не спешу...
     
  10. Valick

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

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    может через месяц или два озвучу готовый вариант, а пока ждём
     
  11. AnonimS

    AnonimS Новичок

    С нами с:
    8 дек 2016
    Сообщения:
    88
    Симпатии:
    9
    Спасибо, решений тут на самом деле не 1, мне показалось самое оптимальном вот это:


    Код (Text):
    1. .... from (
    2. SELECT *
    3. FROM ТаблицаДанных
    4. WHERE ПолеСортировки BETWEEN 1 AND 10
    5. ORDER BY RAND()
    6. ) as t
    7. GROUP BY t.ПолеСортировки
    8. ORDER BY t.ПолеСортировкиASC) ...
    Таким образом не нужно использовать куча запросов и UNION, был еще вариант GROUP_CONCAT()..
     
  12. Valick

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

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    как раз правильный вариант
     
  13. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Вот так можно объединить два совпадения:
    Код (Text):
    1. create table t1(x int, y int);
    2. insert into t1 values(1,1);
    3. insert into t1 values(2,1);
    4. insert into t1 values(3,2);
    5. insert into t1 values(4,3);
    6. insert into t1 values(5,3);
    7. insert into t1 values(6,3);
    8. select t1.y from t1 join
    9. (select x, count(*) as y
    10. from t1 group by y having count(*)=2)
    11. as t2 on t1.x!=t2.x;
     
  14. Valick

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

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @keren, это тихий ужас
     
  15. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям
    А мне кажется, что текстовое описание цели не соответствует приведенному примеру "...что-то типа того". Что-то сгруппировал, а что-то оставил как есть.

    Еще есть обоснованное сомнение на счёт того как ТС использовал группировку здесь. Он исходит из того, что порядок строк до группировки повлияет на выдачу после group by. На самом деле в выдаче могут присутствовать только группируемые поля и агрегаты от других полей. Следствие: никаких случайных записей не будет. Повторный запрос выведет ровно тот же результат.
    --- Добавлено ---
    P.S. Поясню: вот такой запрос ошибочен
    Код (Text):
    1. SELECT * FROM sometable ORDER BY somefield
    при некоторых настройках MySQL не репортит ошибку, но вообще это против стандарта ANSI SQL. потому что непонятно какие именно значения должны браться для всех полей кроме somefield.
    а начиная с версии MySQL 5.7 по умолчанию применяются строгие правила при группировке см. доку
    https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sqlmode_only_full_group_by

    Итого, ты хочешь сделать такое
    Код (Text):
    1. SELECT groupable, sortable
    2. FROM
    3. (SELECT...ORDER BY RAND()) x
    4. GROUP BY groupable
    надеясь получать случайное значение в sortable. Но увы, это приведёт к ошибке.
    А если применишь агрегат к sortable, уйдёшь от ошибки, но лишишся случайности. Например MAX(sortable), SUM(sortable) или GROUP_CONCAT(sortable) дают предсказуемый неслучайный результат.
     
  16. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Задача как я понял, если два повторения во втором столбце:
    а - 1
    к - 1
    вывести а - 1 или к - 1 случайно,
    а строки с 11 не трогать тк повторяется больше двух раз,
    но там есть еще условие, делать это в каждых 10 строках из 1000 строк.
     
  17. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям
    Если 2 повтора, то выбрать одно, а если без повторов или более 2х повторов, то оставить как есть? Это как-то люто вообще. © не верю!
    --- Добавлено ---
    Согласен, что заглавное сообщение выглядит именно так, но....
    --- Добавлено ---
    Если так, то я пошёл отсюда восвояси :)
     
  18. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям