SQL SUM TOP 5 значений для каждой категории, а затем сумма SUM для каждого идентификатора - PullRequest
1 голос
/ 17 мая 2019

Я пытаюсь создать оператор SQL для суммирования 5 лучших значений в категориях по идентификатору пользователя для создания общего итога. Возможно ли это и как мне этого добиться? Я могу суммировать 5 лучших по каждой категории или ВСЕМ, но изо всех сил пытаюсь понять, как я могу СУММИТЬ каждую отдельную общую сумму категории.

Например,

ID           Cater   Weight
--------------------------------
1            Cheese    10
2            Bacon     15
1            Cheese    5
2            Bacon     10
1            Cheese    22
2            Cheese    5
1            Bacon     10
1            Cheese    10
2            Cheese    5
1            Cheese    20
2            Bacon     10
1            Cheese    30

Результаты, которые я ищу,

ID      Total_Weight
-------------------
1            102    Top 5 Cheese (10+22+10+20+30) + Top 5 Bacon (10)
2            45     Top 5 Cheese (5+5) + Top 5 Bacon (15+10+10)

Любые значения за пределами Top 5 игнорируются.

Приведенный ниже код отображает СУММУ 5 лучших весов ВСЕХ категорий КАК общий вес. Могу ли я добиться того, что я хочу от одного заявления

$log = "SELECT id, cater,
    SUM(weight) AS total_weight
   FROM   (   SELECT id,
                 CASE WHEN @ID = ID THEN @ROW_NUMBER := @ROW_NUMBER + 1
                      ELSE @ROW_NUMBER := 1
                  END AS rn,
                 cater,
                 weight,
                 @id := id
            FROM individual,
                 (SELECT @ROW_NUMBER := 1, @ID := '') r
           ORDER
              BY
                 id, weight DESC
      ) TMP
 WHERE rn <= 5
   AND cater <> ''

   GROUP
BY id
 ORDER
BY total_weight DESC";

Ответы [ 2 ]

1 голос
/ 17 мая 2019

Там может быть какое-то другое лучшее решение.Но это обеспечит ожидаемый результат -

SELECT B.id, 
SUM(T_weight) Total_Weight,
group_concat(concat('TOP 5 ',B.cater,' (',B.T,')') SEPARATOR ' ') Details
FROM
(
    SELECT ID,cater,SUM(Weight) T_weight,group_concat(weight SEPARATOR '+') T
    FROM 
    (    
        SELECT *    FROM
        (
            SELECT id,cater, CASE WHEN @ID = ID THEN @ROW_NUMBER := @ROW_NUMBER + 1 ELSE @ROW_NUMBER := 1 END AS rn,weight,@id := id
            FROM your_table,(SELECT @ROW_NUMBER := 1, @ID := ''
        ) r
        WHERE cater = 'Cheese' ORDER BY id, weight DESC
        )A WHERE rn < 6


        UNION ALL

        SELECT *    FROM
        (
            SELECT id,cater, CASE WHEN @ID = ID THEN @ROW_NUMBER := @ROW_NUMBER + 1 ELSE @ROW_NUMBER := 1 END AS rn,weight,@id := id
            FROM your_table,(SELECT @ROW_NUMBER := 1, @ID := ''
        ) r
        WHERE cater = 'Bacon' ORDER BY id, weight DESC
        )A WHERE rn < 6


        UNION ALL

        SELECT *    FROM
        (
            SELECT id,cater, CASE WHEN @ID = ID THEN @ROW_NUMBER := @ROW_NUMBER + 1 ELSE @ROW_NUMBER := 1 END AS rn,weight,@id := id
            FROM your_table,(SELECT @ROW_NUMBER := 1, @ID := ''
        ) r
        WHERE cater = 'Cat3' ORDER BY id, weight DESC
        )A WHERE rn < 6


        UNION ALL

        SELECT *    FROM
        (
            SELECT id,cater, CASE WHEN @ID = ID THEN @ROW_NUMBER := @ROW_NUMBER + 1 ELSE @ROW_NUMBER := 1 END AS rn,weight,@id := id
            FROM your_table,(SELECT @ROW_NUMBER := 1, @ID := ''
        ) r
        WHERE cater = 'Cat4' ORDER BY id, weight DESC
        )A WHERE rn < 6


        UNION ALL

        SELECT *    FROM
        (
            SELECT id,cater, CASE WHEN @ID = ID THEN @ROW_NUMBER := @ROW_NUMBER + 1 ELSE @ROW_NUMBER := 1 END AS rn,weight,@id := id
            FROM your_table,(SELECT @ROW_NUMBER := 1, @ID := ''
        ) r
        WHERE cater = 'Cat5' ORDER BY id, weight DESC
        )A WHERE rn < 6


        UNION ALL

        SELECT *    FROM
        (
            SELECT id,cater, CASE WHEN @ID = ID THEN @ROW_NUMBER := @ROW_NUMBER + 1 ELSE @ROW_NUMBER := 1 END AS rn,weight,@id := id
            FROM your_table,(SELECT @ROW_NUMBER := 1, @ID := ''
        ) r
        WHERE cater = 'Cat6' ORDER BY id, weight DESC
        )A WHERE rn < 6
    )A
    GROUP BY ID,Cater
)B
group by id

Выход -

1   191 TOP 5 Cheese (10+22+20+10+30) TOP 5 Cat3 (25+9+20+16+13) TOP 5 Bacon (10)
2   45  TOP 5 Cheese (5+5) TOP 5 Bacon (15+10+10)
0 голосов
/ 17 мая 2019

Если у вас MySql версии 8 или выше, вы можете использовать этот код:

  SELECT id, SUM (weight)
    FROM (SELECT test.*,
                 ROW_NUMBER ()
                     OVER (PARTITION BY id, categ ORDER BY weight DESC)
                     rn
            FROM test) sub
   WHERE sub.rn < 6
GROUP BY id;

Вам нужен MySql 8+, потому что я использовал функцию row_number и только из версии 8 она существует. В приведенном ниже примере скрипта я использовал Microsoft Sql Server 2017, потому что у них не было MySql 8 или выше.

Вы можете увидеть свой пример здесь .

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...