动态的月份和年份枢轴与错误的排序

时间:2018-03-20 06:58:54

标签: sql sql-server sql-order-by dynamic-pivot

从答案from here我建立了一个对我有利的解决方案,但我仍有一个问题。

我有桌子:

ID     |  Year  |  Month  |     Multiply    | Future |  Current
123    |  2017  |    1    |       1.0       |   25   |   null
123    |  2017  |    2    |       1.0       |   19   |   15
123    |  2017  |    3    |       1.0       |   13   |   0
123    |  2017  |    4    |       1.0       |   22   |   14
123    |  2017  |    5    |       1.0       |   13   |   null
...    |  ....  |   ...   |       ...       |   ..   |   ..
123    |  2018  |    1    |       1.0       |   25   |   10
123    |  2018  |    2    |       1.0       |   25   |   10
...    |  ....  |   ...   |       ...       |   ..   |   ..
124    |  2017  |    1    |       1         |   10   |   5
124    |  2017  |    2    |       1         |   15   |   2
...    |  ....  |   ...   |       ...       |   ..   |   ..
124    |  2018  |    1    |       1         |   20   |   0

我构建此视图以连接Year + Month并生成IF语句: 我从Future和Current列得到的新Value列中的值 - 当Current值为null时获取Future值并乘以Multiply,否则得到Current值并乘以Multiply(偶数0)。在它旁边,我需要在从Future列获取值时添加'F'前缀。

ID    |     Date      |    Value   |
123   |    2017 - 1   |     F25    |
123   |    2017 - 2   |     15     |
123   |    2017 - 3   |     0      |
..    |      ..       |     ..     |

代码:

SELECT  ID = ID,
        [Date] = [Date],
        [Value] = [Value]

FROM    (   SELECT  ID, 
                    cast([Year] as varchar(30)) + ' - ' + cast([Month]as varchar(30)) as [Date],
                    [Multiply],
                    case  when [Current] IS NULL /*OR [Current] = 0*/ 
                    then 'F' + CAST([Future] * [Multiply] as varchar(30))   
                    else CAST([Current] * [Multiply] as varchar(30))  
                    end as Value
            FROM    dbo.CurrentFuture
        ) AS t

从此我通过动态转动来制作这个视图。

ID     |  2017 - 1  |  2017 - 10 |  2017 - 11 |  2017 - 12 |  2017 - 2 | ...  |  2018 - 1  |  ...
123    |    F25     |     ..     |     ..     |    ..      |     15    | ...  |    10      |  ...
124    |      5     |     2      |     ..     |    ..      |     ..    | ...  |     0      |  ...

代码:

    DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT ',' + QUOTENAME([Date]) 
                    from dbo.UpperView
                    group by [Date]
                    order by [Date]
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT [ID],' + @cols + ' from 
             (
                select [ID], [Date],[Value]
                from [dbo].[UpperView]
            ) x
            pivot 
            (
                max([Value])
                for [Date] in (' + @cols + ')
            ) p '

execute(@query);

正如你所看到的,新视图中的列没有以良好的方式排序..而不是2017年 - 2017年1月2日 - 2017年 - 3我2017年1月1日 - 2017年10月 - 2017年11月 - 12,2017 - 2.你能帮我解决一下如何正确排序吗?

2 个答案:

答案 0 :(得分:3)

根据有限的信息,您想要的是基于年级+月的连接字符串的列的排序。

你需要的是在月份前加上" 0" 1月至9月,10月至12月没有前缀。

所以实际上你会实现这一点。

$i = 0;
$j = 0;
foreach($data as $key=>$value){
if($j == 0)
{
$newdata['rules'][$i]['field'] = $value;
}
if($j == 1)
{
$newdata['rules'][$i]['condition'] = $value;
}
if($j == 2)
{
$newdata['rules'][$i]['value'] = $value;
$i++;
}
$j++;
if($j > 2)
{
$j = 0;
}
}

答案 1 :(得分:1)

向UpperView添加新列以进行此类排序

cast([Year] as varchar(30)) + RIGHT('0' + cast([Month] as varchar(30)), 2) as [DateOrder]

并使用此列对列查询进行排序,而不是[日期]

select @cols = STUFF((SELECT ',' + QUOTENAME([Date]) 
                    from dbo.UpperView
                    group by [Date], [DateOrder]
                    order by [DateOrder]
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')