2009-06-11 113 views
1

如何在MySQL中简化此代码?在mySQL中压缩SQL

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 

这样计算的日期数是动态的吗?

+1

我认为这个问题会更容易回答,如果你告诉我们你想要的结果是什么。从一开始,这个查询看起来是个不好的主意。 – Blixt 2009-06-11 09:19:08

回答

0

您不能更改列数动态,但你可以为每个时间得到不同的行很容易:

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 
0

如果我正确理解你,那么我认为你不能做你想做的事情:SQL不能这样工作。如果您的查询正在从另一个程序中使用,并且您知道您感兴趣的日期计数集,那么您可以在提交之前将其构建为一个字符串。如果你想天的所有可能的数字,而且必须有一个SQL查询那么联盟将,我想,这样做(尽管我宁愿两个查询):

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 
1

大概什么效果最好是拆分此成两个查询,一个用于装的平均价格和金额每人价格:

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');