如何将多个枢纽查询的结果水平结合在一起?

时间:2018-09-04 06:10:39

标签: sql vb.net

我可能没有清楚地表达问题,所以在这里我将予以澄清。

我有一个显示数据的VB.NET系统。为了显示数据,我具有以下使用数据透视的SQL存储过程:

    DECLARE @cols AS NVARCHAR(MAX), @query  AS NVARCHAR(MAX)
    select @cols = STUFF((SELECT ',' + QUOTENAME(form_column_id) from
    GetFormColumns(@formTemplateId) FOR XML PATH(''),
    TYPE).value('.', 'NVARCHAR(MAX)') ,1,1,'')

    set @query = N' select *
    from
    (select row_number as Row,fc.form_column_id, fdd.data
    from
    form_data_h fdh
    inner join form_data_d fdd on fdd.form_data_h_id = fdh.form_data_h_id 
    inner join form_column fc on fc.form_column_id = fdd.form_column_id 
    inner join column_header c on c.column_header_id=fc.column_header_id 
    where fdh.is_active = 1 and fdh.form_data_h_id= ' +                         
    CONVERT(varchar(10),@formDataHId) + '  and fc.is_active = 1
    ) src
    pivot(
    min(data)
    for form_column_id in (' + @cols + N')
    ) piv'

    execute(@query);

我必须利用数据透视,因为用户数据输入需要动态。所以从这个... table results

结果现在看起来像这样。 pivot results

此数据具有通过特定参数过滤的不同结果。现在,我已经显示了2017年的作物数据。我想将其与2018年的作物数据结合起来(将根据存储过程参数@formDataHId进行更改)。

那应该导致看起来像这样... 2017 and 2018 results

有什么办法可以在SQL中进行此操作,还是必须在VB.net中进行?如果是这样,我该怎么办?

任何想法都会受到欢迎,因为我现在有点困惑。如果用户需要查看从2016年到2019年的数据,则应这样显示。

1 个答案:

答案 0 :(得分:0)

SQL透视图就足够了。如果每年的数据结构相同,则可以在每年的数据之间使用UNION ALL。然后使用您的查询来确定合并年份的数据。

在我的数据透视功能中,我使用一个名为Test的表来生成数据透视。我还有另外2个表Source2017和Source2018。我使用此查询插入Source2017和Source2018。

INSERT #Test
    SELECT Date, Item, Quantity FROM #Source2017
    UNION ALL
    SELECT Date, Item, Quantity FROM #Source2018

如果我只想要2017年的数据,则从insert语句中删除Source2018。

INSERT #Test
    SELECT Date, Item, Quantity FROM #Source2017

比方说,我还有更多表,Source2015和Source2016。如果我想全部旋转它们,只需使用UNION ALL添加表即可。

INSERT #Test
    SELECT Date, Item, Quantity FROM #Source2015
    UNION ALL
    SELECT Date, Item, Quantity FROM #Source2016
    UNION ALL
    SELECT Date, Item, Quantity FROM #Source2017
    UNION ALL
    SELECT Date, Item, Quantity FROM #Source2018

完整查询:

IF OBJECT_ID('tempdb..#Test') IS NOT NUll DROP TABLE #Test
IF OBJECT_ID('tempdb..#Source2017') IS NOT NUll DROP TABLE #Source2017
IF OBJECT_ID('tempdb..#Source2018') IS NOT NUll DROP TABLE #Source2018

CREATE TABLE #Test
(
    Date DATE,
    Item VARCHAR(100),
    Quantity INT
)

CREATE TABLE #Source2017
(
    Date DATE,
    Item VARCHAR(100),
    Quantity INT
)

CREATE TABLE #Source2018
(
    Date DATE,
    Item VARCHAR(100),
    Quantity INT
)

INSERT #Source2017 VALUES
    ('2017/01/01', 'Mango', 5),
    ('2017/01/01', 'Orange', 6),
    ('2017/01/02', 'Mango', 7),
    ('2017/01/02', 'Orange', 8),
    ('2017/01/02', 'Cherry', 9)

INSERT #Source2018 VALUES
    ('2018/01/01', 'Durian', 15),
    ('2018/01/02', 'Orange', 28),
    ('2018/01/03', 'Cherry', 19)

INSERT #Test
    SELECT Date, Item, Quantity FROM #Source2017
    UNION ALL
    SELECT Date, Item, Quantity FROM #Source2018

DECLARE @SQL AS VARCHAR(MAX)
DECLARE @Columns AS VARCHAR(MAX)
DECLARE @Columns2 AS VARCHAR(MAX)

SELECT @Columns = COALESCE(@Columns + ',','') + QUOTENAME(Date)
FROM (SELECT DISTINCT Date FROM #Test) AS B
ORDER BY B.Date

SELECT @Columns2 = COALESCE(@Columns2 + ',','') + 'ISNULL(' + QUOTENAME(Date) + ', 0) AS [' + CAST(Date AS VARCHAR(100)) + ']'
FROM (SELECT DISTINCT Date FROM #Test) AS B
ORDER BY B.Date

SET @SQL = '
WITH PivotData AS
(
    SELECT Date, Item, Quantity FROM #Test
)
SELECT
    Item, ' + @Columns2 + '
FROM PivotData
PIVOT
(
    SUM(Quantity)
    FOR Date
    IN (' + @Columns + ')
) AS PivotResult
ORDER BY Item'

EXEC(@SQL);

DROP TABLE #Test
DROP TABLE #Source2017
DROP TABLE #Source2018

结果:

+--------+------------+------------+------------+------------+------------+
|  Item  | 2017-01-01 | 2017-01-02 | 2018-01-01 | 2018-01-02 | 2018-01-03 |
+--------+------------+------------+------------+------------+------------+
| Cherry |          0 |          9 |          0 |          0 |         19 |
| Durian |          0 |          0 |         15 |          0 |          0 |
| Mango  |          5 |          7 |          0 |          0 |          0 |
| Orange |          6 |          8 |          0 |         28 |          0 |
+--------+------------+------------+------------+------------+------------+