Медленный запрос, есть ли лучший способ? - PullRequest
1 голос
/ 23 мая 2011

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

Таблица, результат и запрос приведены ниже.Я анонимизировал данные, и у меня есть 8 подзапросов, а не 2, но формат тот же.

Таблица "a":

id      userId       type     amount
------------------------------------
 1      1            a        400
 2      1            b        300
 3      1            c        230
 4      2            a        600
 5      2            b        500
 6      2            c        430

У меня есть индекс для каждогостолбец и один дополнительный, который включает в себя userId и тип столбцов.Я также могу гарантировать, что userId и тип уникальны (то есть, для пользователя 1 не будет двух типов 'a').

Желаемый результат:

userId   typeAtotal  typeBtotal
--------------------------------
  1      400         300
  2      600         500

Мой запрос:

SELECT userId, 
       (SELECT amount 
          FROM a AS a2 
         WHERE a2.userId = a1.userId 
           AND a2.type = 'a') AS aAmt,
       (SELECT amount 
          FROM a AS a3 
         WHERE a3.userId = a1.userId 
           AND a3.type = 'b') AS bAmt
    FROM a AS a1 
   WHERE type IN ('a','b') 
GROUP BY userId

Ответы [ 2 ]

5 голосов
/ 23 мая 2011

Использование:

  SELECT t.userid,
         MAX(CASE WHEN t.type = 'a' THEN amount ELSE NULL END) AS typeAtotal,
         MAX(CASE WHEN t.type = 'b' THEN amount ELSE NULL END) AS typeBtotal
    FROM YOUR_TABLE t
GROUP BY t.userid

Если может быть больше одной суммы для любого типа - это вернет самое высокое. Если вы хотите добавить такие ситуации, используйте SUM:

  SELECT t.userid,
         SUM(CASE WHEN t.type = 'a' THEN amount ELSE NULL END) AS typeAtotal,
         SUM(CASE WHEN t.type = 'b' THEN amount ELSE NULL END) AS typeBtotal
    FROM YOUR_TABLE t
GROUP BY t.userid
1 голос
/ 23 мая 2011

Для меня это выглядит как кросс-табуляция. Вы можете попробовать что-то вроде этого:

SELECT userId, 
    SUM(IF(a.type = 'a'), a.amount, 0) AS aAmount, 
    SUM(IF(a.type = 'b'), a.amount, 0) AS bAmount
FROM a
WHERE type IN ('a', 'b')
GROUP BY a.userId

Возможно, вы захотите прочитать этот довольно хорошо написанный урок: http://dev.mysql.com/tech-resources/articles/wizard/index.html

Редактировать: исправлено условие ELSE.

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