Группировать, только если есть строки, которые нужно сгруппировать - PullRequest
0 голосов
/ 16 марта 2019

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

То, чего я хотел бы достичь, в некоторой степени достигается GROUP BY и HAVING с возможностью CASE WHEN, но что бы я ни делал, я не добиваюсь того, чего желаю.

То, чего я хочу достичь, это GROUP BY только тогда, когда содержимое группы превышает 3 строки и оставляет отдельные элементы, т.е. не сгруппировано , когда группа меньше или равна до трех.

Пример

ID     DESC    VAL1   VAL 2   VAL 3    
1      DESC1    2       2       4    
2      DESC2    2       2       4     
3      DESC3    2       2       4    
4      DESC4    2       2       4     
5      DESC5    1       1       2      
6      DESC6    1       1       2    

GROUP BY будет через VAL1 , VAL2 , VAL 3 через следующие

SELECT * FROM TABLE1 GROUP BY VAL1,VAL2,VAL3

Это даст следующее:

ID     DESC    VAL1   VAL 2   VAL 3    
1      DESC1    2       2       4    
5      DESC5    1       1       2   

Однако мне нужно следующее:

ID     DESC    VAL1   VAL 2   VAL 3    
1      DESC1    2       2       4    
5      DESC5    1       1       2      
6      DESC6    1       1       2 

Может ли это быть достигнуто с помощью GROUP BY, я думаю, что это подзапрос, но я не могу справиться. Ваша помощь будет очень ценится.

СУБД - это MySQL.

Ответы [ 3 ]

0 голосов
/ 16 марта 2019

С UNION ALL, для 2 разных случаев:

select t.* from tablename t inner join (
  select min(id) minid
  from tablename
  group by val1, val2, val3
  having count(*) > 3
) g on g.minid = t.id
union all
select * from tablename t
where (
  select count(*) from tablename 
  where val1 = t.val1 and val2 = t.val2 and val3 = t.val3
) <= 3

См. Демоверсию

0 голосов
/ 16 марта 2019

Если вы используете MySQL 8.0, вы можете достичь этого просто с помощью оконных функций COUNT() и ROW_NUMBER():

SELECT id, descr, val1, val2, val3
FROM (
    SELECT 
        t.*,
        COUNT(*) OVER(PARTITION BY val1, val2, val3) cnt,
        ROW_NUMBER() OVER(PARTITION BY val1, val2, val3 ORDER BY id) rn
    FROM mytable t
) x WHERE cnt < 3 OR rn = 1
ORDER BY id

Во внутреннем запросе cnt указывает, сколько записей имеют val1, va2, val3 с текущей записью. rn присваивает ранг каждой записи в группах записей, имеющих одинаковые val1, va2, val3. Внешний запрос затем использует эти две части информации для фильтрации соответствующих записей.

Демонстрация на DB Fiddle :

| id  | descr | val1 | val2 | val3 |
| --- | ----- | ---- | ---- | ---- |
| 1   | DESC1 | 2    | 2    | 4    |
| 5   | DESC5 | 1    | 1    | 2    |
| 6   | DESC6 | 1    | 1    | 2    |
0 голосов
/ 16 марта 2019

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

Select * 
from table1 
where md5(concat(val1,val2,val3)) in (
    SELECT md5(concat(val1,val2,val3)) 
    FROM TABLE1 
    GROUP BY VAL1,VAL2,VAL3 
    having count(*) > 3) 
group by VAL1,VAL2,VAL3
union
Select * 
from table1 
where md5(concat(val1,val2,val3)) not in (
    SELECT md5(concat(val1,val2,val3)) 
    FROM TABLE1 
    GROUP BY VAL1,VAL2,VAL3 
    having count(*) > 3)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...