SQL-запрос для подсчета уникальных комбинаций в таблице — MySql

У меня есть таблица сопоставления, как показано ниже

c1  c2
--  --
1   1
1   1
1   2
1   3
1   3
2   1
2   2
2   3
3   1

и так далее. В таблице есть отдельный столбец id (здесь не показан). Вот мой запрос до сих пор:

SELECT `c1`, `c2`, COUNT(*) AS `count_of_uniques` FROM `map_table` 
GROUP BY `c1`, `c2` 

Я также пробовал с отдельным запросом, подобным этому.

SELECT `c1`, `c2`, COUNT(DISTINCT `c1`, `c2`) AS `count_of_uniques` FROM `map_table`

Ожидаемый результат

c1  c2  count_of_uniques
--  --  ----------------
1   1   2
1   2   2
1   3   3
2   2   1
2   3   1

Мой текущий запрос показывает правильный вывод, когда комбинация состоит из двух одинаковых чисел, но когда у нас есть что-то вроде 1-2 и 2-1, запрос не дает правильного вывода.

отчетливо показывает еще меньше результатов.

Любая помощь приветствуется. Спасибо.

Ваш ожидаемый результат точно соответствует фактический результат вашего первого запроса. Вы разместили неправильный ожидаемый результат?

GarethD 28.05.2019 15:23

это SQL или MySQL?

Sirmyself 28.05.2019 15:32
"это SQL или MySQL?" @Sirmyself тег SQL не относится к SQL Server (MSSQL) на этом веб-сайте, если вы об этом думаете.
Raymond Nijland 28.05.2019 15:42

@raymond-nijland Тогда я исправляюсь

Sirmyself 28.05.2019 15:44

@GarethD Прошу прощения за неправильные данные. Я пытался сделать вещи простыми, но терял много деталей. Вот собственно проблема

Prashanth Benny 29.05.2019 07:13
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
1
5
162
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Выберите C1,C2,Count(*) из map_table Group By C1,C2 Order by C1

Ответ принят как подходящий

I думать вам может понадобиться что-то, что касается комбинаций, а не перестановок, то есть 1, 2 и 2, 1 следует рассматривать как одну и ту же комбинацию. Если это так, вы можете использовать выражение case, чтобы убедиться, что c1 всегда является меньшим из двух значений, а c2 — большим из двух. Это сгруппирует похожие пары вместе (так что 2, 1 сначала будет перевернуто, чтобы стать 1, 2, а затем сгруппировано со всеми похожими результатами):

SELECT c1, c2, COUNT(*) AS `count_of_uniques` 
FROM (  SELECT CASE WHEN c1 > c2 THEN c2 ELSE c1 END AS c1, 
                CASE WHEN c1 > c2 THEN c1 ELSE c2 END AS c2
        FROM map_table) AS t
GROUP BY c1, c2

Выход

c1      c2      count_of_uniques
-------------------------------
1       1       2
1       2       2
1       3       3
2       2       1
2       3       1

Пример скрипта БД

Лучший ответ, я думаю. Однако вопрос: что было бы более эффективным между использованием функции IF и использованием оператора CASE?

Sirmyself 28.05.2019 15:45

В вопросе показан случай выражение, а не оператор case (разница часто заключается в том, что я педантичен, но в MySQL это более важно, поскольку MySQL имеет как выписка по делу, так и падежное выражение). Тем не менее, это уже спрашивали так и не было исчерпывающего ответа. На самом деле я ожидаю, что любая разница в производительности будет настолько незначительной, что их можно будет считать равными.

GarethD 28.05.2019 16:03

Я знаю SQL Server намного лучше, чем MySQL, и я знаю, что SQL Server, эквивалентный IF() (IIF()), в любом случае переписывается во время компиляции как выражение CASE, поэтому разница в производительности абсолютно нулевая. Я ожидаю, что MySQL будет опережать аналогичную операцию, так что внутренне обе выполняют точно такую ​​​​же операцию.

GarethD 28.05.2019 16:04

Вы можете использовать функции least() и greatest(), чтобы получить пары, по которым вы будете группироваться:

select 
  least(c1, c2) c1, 
  greatest(c1, c2) c2, 
  count(*) count_of_uniques
from map_table  
group by 
  least(c1, c2), 
  greatest(c1, c2)

Смотрите демо.
Результаты:

| c1  | c2  | count_of_uniques |
| --- | --- | ---------------- |
| 1   | 1   | 2                |
| 1   | 2   | 2                |
| 1   | 3   | 3                |
| 2   | 2   | 1                |
| 2   | 3   | 1                |

Другие вопросы по теме