сжать SQL в MySQL - PullRequest
       13

сжать SQL в MySQL

1 голос
/ 11 июня 2009

Как я могу упростить этот код в MySQL?

SELECT name,
  MAX(IF(to_days(thedate) - to_days('2009-06-13') = 0, price, '')) AS date1,
  MAX(IF(to_days(thedate) - to_days('2009-06-13') = 1, price, '')) AS date2,
  MAX(IF(to_days(thedate) - to_days('2009-06-13') = 2, price, '')) AS date3,
  MAX(IF(to_days(thedate) - to_days('2009-06-13') = 3, price, '')) AS date4,
  MAX(IF(to_days(thedate) - to_days('2009-06-13') = 4, price, '')) AS date5,
  MAX(IF(to_days(thedate) - to_days('2009-06-13') = 5, price, '')) AS date6,
  MAX(IF(to_days(thedate) - to_days('2009-06-13') = 6, price, '')) AS date7,
AVG(price),SUM(price)
FROM `personals`
WHERE personal_id = '1234'
GROUP BY name

Так что число рассчитанных дат является динамическим?

Ответы [ 3 ]

1 голос
/ 11 июня 2009

Что, вероятно, работает лучше всего, это разделить это на два запроса, один для загрузки средней цены и суммы цен на человека:

SELECT
  AVG(price), SUM(price)
FROM `personals`
WHERE personal_id = '1234'
GROUP BY name;

и второй максимум, который вы хотите знать:

SELECT
  MAX(price)
FROM `personals`
WHERE personal_id = '1234'
GROUP BY name, to_days(thedate) - to_days('2009-06-13');

Если вы действительно хотите, чтобы все столбцы были в одном запросе, используйте первый подзапрос (может быть не слишком эффективным в больших базах данных)

SELECT
  MAX(price),
  AVG(price),
  SUM(price)
FROM `personals`
LEFT JOIN (
  SELECT
    AVG(price), SUM(price), name
  FROM `personals`
  WHERE personal_id = '1234' -- # this line is optional
  GROUP BY name
) totals
ON totals.name = personals.name
WHERE personal_id = '1234'
GROUP BY name, to_days(thedate) - to_days('2009-06-13');
0 голосов
/ 11 июня 2009

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

SELECT
  name
, to_days(thedate) - to_days('2009-06-13') AS num_days
, MAX(price) As max_price
, NULL AS avg_price
, NULL AS sum_price
FROM `personals`
WHERE personal_id = '1234'
GROUP BY
  name
, to_days(thedate) - to_days('2009-06-13') 
UNION ALL
SELECT
  name
, NULL
, NULL
, AVG(price)
, SUM(price)
FROM `personals`
WHERE personal_id = '1234'
GROUP BY name
0 голосов
/ 11 июня 2009

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

SELECT to_days(thedate) - to_days('2009-06-13') as interval,
   max(price) FROM `personals`
WHERE personal_id = '1234'
GROUP BY name, thedate

Вам нужно сделать отдельный запрос, чтобы получить средние данные:

SELECT name,
   AVG(price),SUM(price)
FROM `personals`
WHERE personal_id = '1234'
GROUP BY name
...