2017-02-10 14 views
1

Я новичок в MySQL и недавно играл с ним. Я здесь, чтобы узнать, поможет ли кто-нибудь мне решить эту проблему, над которой я работал последние несколько дней. В принципе у меня есть следующая таблицаMySQL Count Distinct value multiple column same row

+------+----------+---------+----------+---------+ 
| City | Animal1 | Animal2 | Animal3 | Animal4 | 
+------+----------+---------+----------+---------+ 
| ACY | Lion  | Giraffe | Elephant | Gorilla | 
| AMS | Elephant | Gorilla | Gorilla | Lion | 
| ATL | Tiger | Tiger | Lion  | Tiger | 
| BYU | Elephant | Tiger | Elephant | Lion | 
| QNB | Lemur | Tiger | Lemur | Gorilla | 
+------+----------+---------+----------+---------+ 

Я пытаюсь найти логику, которая будет только положить Города с 3 или более одинаковых животных .. в этом случае в Атланте с тремя Tiger

+------+----------+---------+----------+---------+ 
| City | Animal1 | Animal2 | Animal3 | Animal4 | 
+------+----------+---------+----------+---------+ 
| ATL | Tiger | Tiger | Lion  | Tiger | 
+------+----------+---------+----------+---------+ 


mysql> SELECT count(DISTINCT Animal1,Animal2,Animal3,Animal4) FROM zooAnimal; 
+-------------------------------------------------+ 
| count(DISTINCT Animal1,Animal2,Animal3,Animal4) | 
+-------------------------------------------------+ 
|            5 | 
+-------------------------------------------------+ 

Я играю с DISTINCT и GROUP BY без всякой удачи, любая помощь приветствуется.

+2

44 Можно ли хранить стол как только два столбца CITY и ANIMALE, тогда становится очень легко – DCR

ответ

1

Ваш стол нуждается в нормализации. Существующая структура таблицы затрудняет и неэффективно запрашивать таблицу.

Сказав, что вы можете использовать запрос, как следующий, чтобы получить City коды, имеющие 3 или более одного и того же животного:

SELECT DISTINCT City 
FROM (
    SELECT City, Animal1 AS Animal 
    FROM mytable 

    UNION ALL 

    SELECT City, Animal2 AS Animal 
    FROM mytable 

    UNION ALL 

    SELECT City, Animal3 AS Animal 
    FROM mytable 

    UNION ALL 

    SELECT City, Animal4 AS Animal 
    FROM mytable 
) AS t 
GROUP BY City, Animal 
HAVING COUNT(*) >= 3 

Edit: Чтобы получить 2 + 2 соответсвующей записи, которые вы можете использовать;

SELECT City 
FROM (
    SELECT City, Animal 
    FROM (
     SELECT City, Animal1 AS Animal 
     FROM mytable 

     UNION ALL 

     SELECT City, Animal2 AS Animal 
     FROM mytable 

     UNION ALL 

     SELECT City, Animal3 AS Animal 
     FROM mytable 

     UNION ALL 

     SELECT City, Animal4 AS Animal 
     FROM mytable 
    ) AS t 
    GROUP BY City, Animal 
    HAVING COUNT(*) >= 2) AS x 
GROUP BY City 
HAVING COUNT(*) >= 2 
+0

хорошая идея - проголосовать вверх –

+0

Идеально это работает как шарм, я пытаюсь изучить основы объединений, союзов и т. Д. Я просто пытаюсь объединиться с MySQL, и это забавно. Я считаю, что нормализация - это следующий мой список, чтобы учиться и играть с ним. – tom1123

+0

Если я могу задать еще один вопрос, как бы вы узнали, где у вас есть два животного? – tom1123

2

Вы можете использовать unpivoting трюк (с помощью перекрестного соединения) для UNPIVOT таблицы, а затем сделать агрегации, как это:

select 
    city, 
    animal 
from (
    select 
     t.city, 
     case x.i 
      when 1 then Animal1 
      when 2 then Animal2 
      when 3 then Animal3 
      when 4 then Animal4 
     end animal 
    from your_table t 
    cross join (
     select 1 i union all 
     select 2 i union all 
     select 3 i union all 
     select 4 i 
    ) x 
) t group by city, animal 
having count(*) >= 3; 

Обратите внимание, что этот запрос читает таблицу только один раз.

Кроме того, было бы лучше исправить ваш дизайн, т. Е. Держать каждое животное в отдельном ряду.

+0

Спасибо, этот метод работает очень хорошо .. – tom1123

+2

Умный трюк, первый раз, я его вижу, так что проголосуйте! –