За последние 24 часа нас посетили 22355 программистов и 1039 роботов. Сейчас ищут 620 программистов ...

Как подсчитать все поля?

Тема в разделе "MySQL", создана пользователем Dimon2x, 16 окт 2018.

  1. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.199
    Симпатии:
    184
    Надо посчитать одним запросом сколько мастеров для каждого города, почему подсчёт не объединяется и как это сделать?

    Код (Text):
    1. CREATE TABLE `master_user` (
    2.   `id` int(10) UNSIGNED NOT NULL,
    3.   `user_id` int(11) NOT NULL,
    4.   `master_id` int(11) NOT NULL,
    5.   `city_id` int(11) DEFAULT NULL
    6. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
    7.  
    8. --
    9. -- Дамп данных таблицы `master_user`
    10. --
    11.  
    12. INSERT INTO `master_user` (`id`, `user_id`, `master_id`, `city_id`) VALUES
    13. (15, 16, 3, 4019),
    14. (18, 16, 5, 4019),
    15. (19, 16, 4, 4019),
    16. (20, 16, 2, 4019),
    17. (21, 17, 4, 4019),
    18. (22, 17, 2, 4400);
    19.  
    20. --
    21. -- Индексы сохранённых таблиц
    22. --
    23.  
    24. --
    25. -- Индексы таблицы `master_user`
    26. --
    27. ALTER TABLE `master_user`
    28.   ADD PRIMARY KEY (`id`);
    29.  
    30. --
    31. -- AUTO_INCREMENT для сохранённых таблиц
    32. --
    33.  
    34. --
    35. -- AUTO_INCREMENT для таблицы `master_user`
    36. --
    37. ALTER TABLE `master_user`
    38.   MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=23;
    39. COMMIT;
    Код (Text):
    1. SELECT master_id, COUNT(*) FROM master_user WHERE city_id = 4019 GROUP BY id
     
  2. username

    username Новичок

    С нами с:
    6 июл 2017
    Сообщения:
    225
    Симпатии:
    17
    почему ты группируешь по айди, а не по городу?
     
  3. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    И группировать по городу (id города), и лишнее условие убрать, и id мастера в результате выборки заменить на id (или название, полученное после связки с таблицей-словарём городов) города.
    И учесть, что хоть mysql не всегда (в зависимости от настроек) ругается, если в выборку включаются данные, неоднозначно соответствующие правилам группировки, всё-таки не надо этим злоупотреблять ввиду высокой вероятности получения данных, не полностю отражающих сложившуюся ситуацию.
     
  4. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.199
    Симпатии:
    184
    Не понимаю, почему не работает, когда я присоединяю ещё одну таблицу?
    Почему-то ругается на этот join

    Код (Text):
    1.  LEFT JOIN category_letter_master ON category_letter_master.masters_id  = master_user.master_id
    Код (Text):
    1. Статический анализ:
    2.  
    3. Найдено 2 ошибок при анализе.
    4.  
    5. Этот тип предложения ранее анализировался. (near "LEFT JOIN" at position 233)
    6. Неизвестный оператор. (near "LEFT JOIN" at position 233)
    7. SQL запрос:
    8.  
    9. SELECT master_user.master_id, masters.specialization, COUNT(*) FROM master_user LEFT JOIN masters ON master_user.master_id = masters.id WHERE city_id = 4019 LEFT JOIN category_letter_master ON category_letter_master.masters_id = master_user.master_id GROUP BY master_user.master_id
    10.  
    11. Ответ MySQL:
    12.  
    13. #1064 - У вас ошибка в запросе. Изучите документацию по используемой версии MySQL на предмет корректного синтаксиса около 'LEFT JOIN category_letter_master ON category_letter_master.masters_id  = master_' на строке 5
    Вот так работает

    Код (Text):
    1. SELECT master_user.master_id,
    2. masters.specialization,
    3. COUNT(*) FROM master_user
    4. LEFT JOIN masters ON master_user.master_id = masters.id
    5.         WHERE city_id = 4019
    6. GROUP BY master_user.master_id
    А если добавить ещё один join, то не работает, почему?

    Код (Text):
    1. --
    2. -- Структура таблицы `category_letter_master`
    3. --
    4.  
    5. CREATE TABLE `category_letter_master` (
    6.   `id` int(10) UNSIGNED NOT NULL,
    7.   `category_letter_id` int(11) NOT NULL,
    8.   `master_id` int(11) NOT NULL
    9. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
    10.  
    11. --
    12. -- Дамп данных таблицы `category_letter_master`
    13. --
    14.  
    15. INSERT INTO `category_letter_master` (`id`, `category_letter_id`, `master_id`) VALUES
    16. (1, 1, 1),
    17. (2, 4, 2),
    18. (3, 5, 3),
    19. (4, 17, 4),
    20. (5, 17, 5),
    21. (7, 12, 7);
    22.  
    23. --
    24. -- Индексы сохранённых таблиц
    25. --
    26.  
    27. --
    28. -- Индексы таблицы `category_letter_master`
    29. --
    30. ALTER TABLE `category_letter_master`
    31.   ADD PRIMARY KEY (`id`);
    32.  
    33. --
    34. -- AUTO_INCREMENT для сохранённых таблиц
    35. --
    36.  
    37. --
    38. -- AUTO_INCREMENT для таблицы `category_letter_master`
    39. --
    40. ALTER TABLE `category_letter_master`
    41.   MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=8;
    42. COMMIT;
    --- Добавлено ---
    Код (Text):
    1. --
    2. -- Структура таблицы `masters`
    3. --
    4.  
    5. CREATE TABLE `masters` (
    6.   `id` int(10) UNSIGNED NOT NULL,
    7.   `specialization` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL
    8. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
    9.  
    10. --
    11. -- Дамп данных таблицы `masters`
    12. --
    13.  
    14. INSERT INTO `masters` (`id`, `specialization`) VALUES
    15. (1, 'Алмазная резка'),
    16. (2, 'Гипсокартон'),
    17. (3, 'Двери'),
    18. (4, 'Пол'),
    19. (5, 'Потолок'),
    20. (7, 'Кладка');
    21.  
    22. --
    23. -- Индексы сохранённых таблиц
    24. --
    25.  
    26. --
    27. -- Индексы таблицы `masters`
    28. --
    29. ALTER TABLE `masters`
    30.   ADD PRIMARY KEY (`id`);
    31.  
    32. --
    33. -- AUTO_INCREMENT для сохранённых таблиц
    34. --
    35.  
    36. --
    37. -- AUTO_INCREMENT для таблицы `masters`
    38. --
    39. ALTER TABLE `masters`
    40.   MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=8;
    41. COMMIT;
     
  5. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.792
    Симпатии:
    650
    Все присоединения (LEFT JOIN) нужно писать до условия (WHERE).
     
    Dimon2x нравится это.
  6. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.199
    Симпатии:
    184
    @miketomlin

    Сделал, заработало, теперь при выборке добавил category_letter_master.category_letter_id,
    и выдаёт ошибку

    Код (Text):
    1. #1055 - Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'prorab.category_letter_master.category_letter_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
    Гугл не помог.

    Вот так работает

    Код (Text):
    1.     SELECT master_user.master_id,
    2. masters.specialization,
    3.            
    4. COUNT(*) FROM master_user
    5.  
    6. LEFT JOIN masters ON master_user.master_id = masters.id
    7. LEFT JOIN category_letter_master ON category_letter_master.master_id  = master_user.master_id
    8.  
    9. WHERE city_id = 4019
    10. GROUP BY master_user.master_id
    Вот так ошибка

    Код (Text):
    1. SELECT master_user.master_id,
    2. masters.specialization,
    3.             category_letter_master.category_letter_id,
    4. COUNT(*) FROM master_user
    5.  
    6. LEFT JOIN masters ON master_user.master_id = masters.id
    7. LEFT JOIN category_letter_master ON category_letter_master.master_id  = master_user.master_id
    8.  
    9. WHERE city_id = 4019
    10. GROUP BY master_user.master_id
     
  7. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    Именно об этом я и упоминал чуть ранее.
    Поле, не включенное в group by и не входящее ни в одну из агрегатных функций (sum, count, avg...).
    Тут либо добавить группировку по этому полю, либо использовать его в качестве параметра агрегатной функции.
    --- Добавлено ---
    В общем, опять так не любимый Вами туториал (один из): Предложение GROUP BY
    :)
     
  8. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.199
    Симпатии:
    184
    @Sail Вот так заработало, только не полностью понимаю, как

    Код (Text):
    1. SELECT
    2. master_user.master_id,
    3. masters.specialization,
    4. category_letter_master.category_letter_id AS aaa,
    5. COUNT(*)
    6.  
    7. FROM master_user
    8.  
    9. LEFT JOIN masters ON master_user.master_id = masters.id
    10. LEFT JOIN category_letter_master ON category_letter_master.master_id = master_user.master_id
    11.  
    12. WHERE city_id = 4019 GROUP
    13.  
    14. BY master_user.master_id, aaa
     
  9. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    Вариант с добавлением поля в выражение группировки.
    Дозволили воспользоваться псевдонимом :)
     
  10. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.199
    Симпатии:
    184
    Нужно теперь посчитать, количество людей не для города, а для страны и региона и я решил, что бы не писать огромный sql запрос, сделать для этого отдельные таблицы.

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

    Нормальный способ?
    --- Добавлено ---
    О, у меня же есть таблица master_user, вот и её и можно расширить, добавив в неё ид страны и ид города, и немного изменить запрос и всё.