按年度排序数据

时间:2015-06-08 19:33:35

标签: sql

我是SQL的新手,实际上只运行了很少修改的语句。我目前正在尝试修改此特定查询:

    public void remove(CustomObject msg ){
                mlist.remove(msg);
                notifyDataSetChanged(); 
    }

    public void remove(int ID){

            int size = mlist.size()-1;
            for(int i=size; i>=0; i--){
                if( mlist.get(i).getId() == ID)     {
                        mlist.remove(i);
                        break;
                }
            }
            notifyDataSetChanged(); 

        }

我想从查询中得到的不是按月分类,而是按特定位置(platformid)可用的所有年份排序。到目前为止,我刚刚修改了脚本,看起来像这样:

    SELECT DISTINCT (ROUND (windspeed * 2, -1) / 2) AS wndspd,
            SUM (CASE WHEN month = 1 THEN 1 ELSE NULL END) AS January,
            SUM (CASE WHEN month = 2 THEN 1 ELSE NULL END) AS February,
            SUM (CASE WHEN month = 3 THEN 1 ELSE NULL END) AS March,
            SUM (CASE WHEN month = 4 THEN 1 ELSE NULL END) AS April,
            SUM (CASE WHEN month = 5 THEN 1 ELSE NULL END) AS May,
            SUM (CASE WHEN month = 6 THEN 1 ELSE NULL END) AS June,
            SUM (CASE WHEN month = 7 THEN 1 ELSE NULL END) AS July,
            SUM (CASE WHEN month = 8 THEN 1 ELSE NULL END) AS August,
            SUM (CASE WHEN month = 9 THEN 1 ELSE NULL END) AS September,
            SUM (CASE WHEN month = 10 THEN 1 ELSE NULL END) AS October,
            SUM (CASE WHEN month = 11 THEN 1 ELSE NULL END) AS November,
            SUM (CASE WHEN month = 12 THEN 1 ELSE NULL END) AS December
    FROM table1
    WHERE    platformid = 'coollocation'
     AND networktype = 'typeofcoollocation'
     AND (windspeedqc <> '2' OR windspeedqc IS NULL)
    GROUP BY ROUND (windspeed * 2, -1) / 2
    ORDER BY ROUND (windspeed * 2, -1) / 2;

问题在于我知道这些年是从1957年到2015年。我非常确定有一种更有效的方法来列出我想要的信息,而不是每年创建一个特定的SUM字符串。我不知道怎么做。请帮忙!

2 个答案:

答案 0 :(得分:1)

您可以尝试创建PIVOT查询

SELECT wndspd, [1957], [1958], [1959],...etc....[2013], [2014], [2015] FROM
(
SELECT (ROUND (windspeed * 2, -1) / 2) AS wndspd,
        YEAR(observationtime) yr
FROM    table1
WHERE   platformid = 'coollocation'
        AND networktype = 'typeofcoollocation'
        AND (windspeedqc <> '2' OR windspeedqc IS NULL)
) src
PIVOT (
    COUNT(yr)
    FOR yr IN ([1957],[1958], [1959],...etc....[2013], [2014], [2015])
) pvt

你必须填写1959年到2013年之间的所有其他年份。

这是一种更简单的方法来创建从1957年到当年的所有列。

DECLARE @PivotCols VARCHAR(MAX),
        @MinYear INT = 1957,
        @CurYear INT = YEAR(GETDATE())
WHILE @MinYear < @CurYear
BEGIN
    SET @PivotCols = COALESCE( @PivotCols + '],[', '[') + CONVERT(VARCHAR, @MinYear)
    SET @MinYear = @MinYear + 1
END

SET @PivotCols = CONCAT(@PivotCols,'],[',CONVERT(VARCHAR, @MinYear),']')

DECLARE @Sql VARCHAR(MAX) = '
SELECT wndspd, ' + @PivotCols + ' FROM
(
SELECT (ROUND (windspeed * 2, -1) / 2) AS wndspd,
        YEAR(observationtime) yr
FROM    table1
WHERE   platformid = ''coollocation''
        AND networktype = ''typeofcoollocation''
        AND (windspeedqc <> ''2'' OR windspeedqc IS NULL)
) src
PIVOT (
    COUNT(yr)
    FOR yr IN (' + @PivotCols + ')
) pvt
'
EXEC (@Sql)

答案 1 :(得分:0)

我认为你基本上是想要这样做:

SELECT DISTINCT (ROUND (windspeed * 2, -1) / 2) AS wndspd
 ,TO_CHAR(observationtime, 'YYYY') as year, 
 ,COUNT(1) as occurrences
FROM table1
WHERE platformid = 'coollocation'
 AND networktype = 'typeofcoollocation'
 AND (windspeedqc <> '2' OR windspeedqc IS NULL)
GROUP BY (ROUND(windspeed * 2, -1) / 2), TO_CHAR(observationtime, 'YYYY')
ORDER BY 1, 2;

...然而,每年的发生次数将由行而不是列表示。

不幸的是,没有简单的方法可以将此查询中的行转换为列,因为您基本上需要知道有多少列并确保每行都正确填充了值。

在一天结束时,您需要为SELECT子句每年添加一行。它看起来像这样:

SELECT yearly.wndspd
 ,SUM(CASE WHEN yearly.year='1957' THEN yearly.occurrences ELSE 0 END) as 1957
 ,SUM(CASE WHEN yearly.year='1958' THEN yearly.occurrences ELSE 0 END) as 1958
 ...
 ,SUM(CASE WHEN yearly.year='2015' THEN yearly.occurrences ELSE 0 END) as 2015
FROM
  (SELECT DISTINCT (ROUND (windspeed * 2, -1) / 2) AS wndspd
   ,TO_CHAR(observationtime, 'YYYY') as year, 
   ,COUNT(1) as occurrences
  FROM table1
  WHERE platformid = 'coollocation'
   AND networktype = 'typeofcoollocation'
   AND (windspeedqc <> '2' OR windspeedqc IS NULL)
  GROUP BY (ROUND(windspeed * 2, -1) / 2), TO_CHAR(observationtime, 'YYYY')) yearly
GROUP BY yearly.wndspd
ORDER BY 1, 2;