查询 - 日期作为列标题

时间:2016-09-02 12:45:04

标签: sql postgresql pivot

我有这个返回结果的查询:

查询

DECLARE @SQLIMG VARCHAR(MAX),
    @IMG_PATH VARBINARY(MAX),
    @TIMESTAMP VARCHAR(MAX),
    @ObjectToken INT,
    @Filename varchar(max)

DECLARE IMGPATH CURSOR FAST_FORWARD FOR 
        SELECT csl_CompanyLogo, [filename] from mlm_CSCompanySettingsLocalizations

OPEN IMGPATH 

FETCH NEXT FROM IMGPATH INTO @IMG_PATH , @Filename

WHILE @@FETCH_STATUS = 0
    BEGIN
        SET @TIMESTAMP = 'd:\' + @Filename + '.bmp'

        PRINT @TIMESTAMP
        PRINT @SQLIMG

        EXEC sp_OACreate 'ADODB.Stream', @ObjectToken OUTPUT
        EXEC sp_OASetProperty @ObjectToken, 'Type', 1
        EXEC sp_OAMethod @ObjectToken, 'Open'
        EXEC sp_OAMethod @ObjectToken, 'Write', NULL, @IMG_PATH
        EXEC sp_OAMethod @ObjectToken, 'SaveToFile', NULL, @TIMESTAMP, 2
        EXEC sp_OAMethod @ObjectToken, 'Close'
        EXEC sp_OADestroy @ObjectToken

        FETCH NEXT FROM IMGPATH INTO @IMG_PATH , @Filename
    END 

CLOSE IMGPATH
DEALLOCATE IMGPATH

结果

select 
   d.veiculo, d.data_op, d.total_custo_op
from 
   fato_distribuicao d
left join dim_frota f 
   on d.veiculo = f.placa
left join schema_staging.staging_rotas_percorridas p 
   on p.placa = d.veiculo and p.data_operacao = d.data_op
where 
   d.uneg_dist = 'RJA'
   and d.data_op between '2016-07-18' and '2016-07-23'
   and f.tipo1 = 'AGREGADO'
group by d.veiculo, d.data_op, d.total_custo_op, p.setor
order by d.veiculo, d.data_op;

但我需要转换此结果并将此查询作为列标题和veiculo data_op total_custo_op BTB7632 2016-07-19 219 BTB7632 2016-07-21 150 BTB7632 2016-07-22 176 DMI1082 2016-07-18 150 DMI1082 2016-07-19 168 DMI1082 2016-07-20 136 DMI1082 2016-07-21 163 DMI1082 2016-07-22 184 EJC1713 2016-07-18 205 EJC1713 2016-07-19 185 EJC1713 2016-07-20 190 EJC1713 2016-07-21 200 EJC1713 2016-07-22 179 GZG1647 2016-07-18 248 GZG1647 2016-07-20 279 GZG1647 2016-07-21 276 GZG1647 2016-07-22 314 GZG1647 2016-07-23 188 作为数据提供日期范围,如下所示:

预期

total_custo_op

我使用 ARRAY_AGG 进行了透视查询,但我可以将日期作为数据分开。我不能使用tablefunc模块。

1 个答案:

答案 0 :(得分:1)

修复基本查询

首先,您的查询存在问题。您有LEFT JOIN,后跟WHERE条件,这是无稽之谈。

如果您确实需要f.tipo1 = 'AGREGADO',请将条件LEFT JOIN移至join子句。但是在你的查询中这没有意义。相反,请使用普通JOIN

p.setor添加到GROUP BY而你没有在结果中显示它是毫无意义的。实际上,GROUP BY根本没有任何意义,因为你没有聚合任何东西。您可能正在寻找DISTINCTDISTINCT ON

所以:

SELECT d.veiculo, d.data_op, d.total_custo_op
FROM   fato_distribuicao d
JOIN   dim_frota         f ON f.placa = d.veiculo
LEFT   JOIN schema_staging.staging_rotas_percorridas p ON p.placa = d.veiculo
                                                      AND p.data_operacao = d.data_op
WHERE  d.uneg_dist = 'RJA'
AND    d.data_op BETWEEN '2016-07-18' AND '2016-07-23'
AND    f.tipo1 = 'AGREGADO'
-- GROUP  BY d.veiculo, d.data_op, d.total_custo_op  -- , p.setor  -- ??
ORDER  BY d.veiculo, d.data_op;

枢轴解决方案

要在没有crosstab() 的情况下移动,您可以在CASE语句中使用聚合,如下所示:

SELECT veiculo
     , min(CASE WHEN data_op = '2016-07-18' THEN total_custo_op END) AS "2016-07-18"
     , min(CASE WHEN data_op = '2016-07-19' THEN total_custo_op END) AS "2016-07-19"
     , -- etc.
FROM  (
  <query from above>
   ) sub
GROUP  BY 1;

crosstab()会更快更优雅: