简体   繁体   English

SQL Server 2014:如何在 csv 导出中包含标题和详细信息

[英]SQL Server 2014: How to include header and detail in csv export

I am trying to produce a script to export csv file to show header record and a corresponding detail record.我正在尝试生成一个脚本来导出 csv 文件以显示标题记录和相应的详细记录。

As an example the output needs to be例如,输出需要是

20138000100012, H,  2013800010, 03.04.2017, WK, 001,    2,  21.05.1984, NULL,   C
20138000100012, D,  INSURE, 0.71
20138000100012, D,  RENT,   98.58
20138000200060, H,  2013800020, 02.04.2018, WK, 006,    0,  25.05.2009, NULL,   C
20138000200060, D,  INSURE, 0.80
20138000200060, D,  RENT,   98.58
20138000500052, D,  LAUNDR, 1.29

I have attempted to produce that using the T-SQL script below:我尝试使用下面的 T-SQL 脚本来生成它:

select * 
from 
    (select 
         cast(dbo.[RE-TENANCY].[TENANCY-REF] as nvarchar) AS [0],
         'H' as [RowLevel],
         substring(convert(varchar(10),dbo.[RE-TENANCY].[TENANCY-REF]), 1, 10) AS [1],
         -- convert(varchar,dbo.[IH-PLACE-CHG].[START-DATE],104) AS [  ]
         format(dbo.[IH-PLACE-CHG].[START-DATE], 'dd.MM.yyyy') AS [2],
         dbo.[RE-TENANCY].[RENT-GROUP] AS [3], 
         cast(substring( dbo.[RE-TENANCY].[TENANCY-REF],11,3) as nvarchar) AS [4]
, cast(substring( dbo.[RE-TENANCY].[TENANCY-REF],14,1) as nvarchar) AS [5]
, cast(format(dbo.[RE-TENANCY].[TNCY-START], 'dd.MM.yyyy') as nvarchar) AS [6]
, cast(format(dbo.[RE-TENANCY].[TNCY-END], 'dd.MM.yyyy') as nvarchar) AS [7]
, substring(dbo.[RE-TENANCY].[TNCY-STATUS],1,1) AS [8]
    FROM            
        dbo.[RE-EX-RAISE-DEBIT-DTL] 
    INNER JOIN
        dbo.[RE-TENANCY] ON dbo.[RE-EX-RAISE-DEBIT-DTL].REFERENCE = dbo.[RE-TENANCY].[TENANCY-REF] 
    INNER JOIN
        dbo.[IH-PLACE-CHG] ON substring(dbo.[RE-TENANCY].[TENANCY-REF],1,10) = dbo.[IH-PLACE-CHG].[PLACE-REF]

    union

select cast(dbo.[RE-TENANCY].[TENANCY-REF] as nvarchar) AS [0]
,'D' as [RowLevel]

, dbo.[RE-EX-RAISE-DEBIT-DTL].[ACCOUNT-CODE] AS [1]
, convert(varchar,[dbo].[RE-EX-RAISE-DEBIT-DTL].[CHARGE-AMT]) AS [2]
, '' AS [3]
, '' AS [4]
, '' AS [5]
, '' AS [6]
, '' AS [7]
, '' AS [8]
FROM            dbo.[RE-EX-RAISE-DEBIT-DTL] INNER JOIN
                         dbo.[RE-TENANCY] ON dbo.[RE-EX-RAISE-DEBIT-DTL].REFERENCE = dbo.[RE-TENANCY].[TENANCY-REF] INNER JOIN
                         dbo.[IH-PLACE-CHG] ON substring(dbo.[RE-TENANCY].[TENANCY-REF],1,10) = dbo.[IH-PLACE-CHG].[PLACE-REF]


) AS HBfile order by cast(HBfile.[0] as bigint), HBfile.[6] desc

but this code incorrectly generates the results below:但此代码错误地生成以下结果:

20138000100012, H,  2013800010, 03.04.2017, WK, 001,    2,  21.05.1984, NULL,   C
20138000100012, H,  2013800010, 04.04.2016, WK, 001,    2,  21.05.1984, NULL,   C
20138000100012, H,  2013800010, 02.04.2018, WK, 001,    2,  21.05.1984, NULL,   C
20138000100012, D,  INSURE, 0.71
20138000100012, D,  RENT,   98.58
20138000200060, H,  2013800020, 02.04.2018, WK, 006,    0,  25.05.2009, NULL,   C
20138000200060, H,  2013800020, 03.04.2017, WK, 006,    0,  25.05.2009, NULL,   C
20138000200060, H,  2013800020, 04.04.2016, WK, 006,    0,  25.05.2009, NULL,   C
20138000200060, D,  INSURE, 0.80
20138000200060, D,  RENT,   98.58
20138000500060, D,  LAUNDR, 1.29

Any thoughts, assistance appreciated.任何想法,帮助表示赞赏。 Thanks谢谢

Use a WHERE clause to filter out the undesired header rows.使用 WHERE 子句过滤掉不需要的标题行。 Desirability seems to be based on the first date column in your results.合意性似乎基于结果中的第一个日期列。

Trying to figure out the issue试图找出问题

Since the duplication is in the Headers part then you should take a look at the headers query:由于重复位于 Headers 部分,因此您应该查看 headers 查询:

select * 
from 
    (select 
         cast(dbo.[RE-TENANCY].[TENANCY-REF] as nvarchar) AS [0],
         'H' as [RowLevel],
         substring(convert(varchar(10),dbo.[RE-TENANCY].[TENANCY-REF]), 1, 10) AS [1],
         -- convert(varchar,dbo.[IH-PLACE-CHG].[START-DATE],104) AS [  ]
         format(dbo.[IH-PLACE-CHG].[START-DATE], 'dd.MM.yyyy') AS [2],
         dbo.[RE-TENANCY].[RENT-GROUP] AS [3], 
         cast(substring( dbo.[RE-TENANCY].[TENANCY-REF],11,3) as nvarchar) AS [4]
, cast(substring( dbo.[RE-TENANCY].[TENANCY-REF],14,1) as nvarchar) AS [5]
, cast(format(dbo.[RE-TENANCY].[TNCY-START], 'dd.MM.yyyy') as nvarchar) AS [6]
, cast(format(dbo.[RE-TENANCY].[TNCY-END], 'dd.MM.yyyy') as nvarchar) AS [7]
, substring(dbo.[RE-TENANCY].[TNCY-STATUS],1,1) AS [8]
    FROM            
        dbo.[RE-EX-RAISE-DEBIT-DTL] 
    INNER JOIN
        dbo.[RE-TENANCY] ON dbo.[RE-EX-RAISE-DEBIT-DTL].REFERENCE = dbo.[RE-TENANCY].[TENANCY-REF] 
    INNER JOIN
        dbo.[IH-PLACE-CHG] ON substring(dbo.[RE-TENANCY].[TENANCY-REF],1,10) = dbo.[IH-PLACE-CHG].[PLACE-REF]

This query contains 2 inner joins which means that the rows generated can be more than the sources count if the join is not made on 1-1 relation.此查询包含 2 个内部联接,这意味着如果未在 1-1 关系上进行联接,则生成的行可能会超过源计数。

After checking the output you provided:检查您提供的输出后:

20138000100012, H,  2013800010, 03.04.2017, WK, 001,    2,  21.05.1984, NULL,   C
20138000100012, H,  2013800010, 04.04.2016, WK, 001,    2,  21.05.1984, NULL,   C
20138000100012, H,  2013800010, 02.04.2018, WK, 001,    2,  21.05.1984, NULL,   C
20138000100012, D,  INSURE, 0.71
20138000100012, D,  RENT,   98.58
20138000200060, H,  2013800020, 02.04.2018, WK, 006,    0,  25.05.2009, NULL,   C
20138000200060, H,  2013800020, 03.04.2017, WK, 006,    0,  25.05.2009, NULL,   C
20138000200060, H,  2013800020, 04.04.2016, WK, 006,    0,  25.05.2009, NULL,   C
20138000200060, D,  INSURE, 0.80
20138000200060, D,  RENT,   98.58
20138000500060, D,  LAUNDR, 1.29

All header columns are identical except the fourth column that is generated using this command:除了使用以下命令生成的第四列之外,所有标题列都相同:

format(dbo.[IH-PLACE-CHG].[START-DATE], 'dd.MM.yyyy') AS [2]

Solution解决方案

If you need only the first value then you can use First_Value() window function:如果您只需要第一个值,那么您可以使用First_Value()窗口函数:

FIRST_VALUE(format(dbo.[IH-PLACE-CHG].[START-DATE], 'dd.MM.yyyy')) OVER(PARTITION BY  cast(dbo.[RE-TENANCY].[TENANCY-REF] as nvarchar)) as [2]

And you can add a distinct operator on the headers query, the whole SQL command will be like:您可以在标题查询上添加一个不同的运算符,整个 SQL 命令将如下所示:

select * 
from 
    (select Distinct 
         cast(dbo.[RE-TENANCY].[TENANCY-REF] as nvarchar) AS [0],
         'H' as [RowLevel],
         substring(convert(varchar(10),dbo.[RE-TENANCY].[TENANCY-REF]), 1, 10) AS [1],
         -- convert(varchar,dbo.[IH-PLACE-CHG].[START-DATE],104) AS [  ]
         FIRST_VALUE(format(dbo.[IH-PLACE-CHG].[START-DATE], 'dd.MM.yyyy')) OVER(PARTITION BY  cast(dbo.[RE-TENANCY].[TENANCY-REF] as nvarchar)) as [2],
         dbo.[RE-TENANCY].[RENT-GROUP] AS [3], 
         cast(substring( dbo.[RE-TENANCY].[TENANCY-REF],11,3) as nvarchar) AS [4]
, cast(substring( dbo.[RE-TENANCY].[TENANCY-REF],14,1) as nvarchar) AS [5]
, cast(format(dbo.[RE-TENANCY].[TNCY-START], 'dd.MM.yyyy') as nvarchar) AS [6]
, cast(format(dbo.[RE-TENANCY].[TNCY-END], 'dd.MM.yyyy') as nvarchar) AS [7]
, substring(dbo.[RE-TENANCY].[TNCY-STATUS],1,1) AS [8]
    FROM            
        dbo.[RE-EX-RAISE-DEBIT-DTL] 
    INNER JOIN
        dbo.[RE-TENANCY] ON dbo.[RE-EX-RAISE-DEBIT-DTL].REFERENCE = dbo.[RE-TENANCY].[TENANCY-REF] 
    INNER JOIN
        dbo.[IH-PLACE-CHG] ON substring(dbo.[RE-TENANCY].[TENANCY-REF],1,10) = dbo.[IH-PLACE-CHG].[PLACE-REF]

    union

select cast(dbo.[RE-TENANCY].[TENANCY-REF] as nvarchar) AS [0]
,'D' as [RowLevel]

, dbo.[RE-EX-RAISE-DEBIT-DTL].[ACCOUNT-CODE] AS [1]
, convert(varchar,[dbo].[RE-EX-RAISE-DEBIT-DTL].[CHARGE-AMT]) AS [2]
, '' AS [3]
, '' AS [4]
, '' AS [5]
, '' AS [6]
, '' AS [7]
, '' AS [8]
FROM            dbo.[RE-EX-RAISE-DEBIT-DTL] INNER JOIN
                         dbo.[RE-TENANCY] ON dbo.[RE-EX-RAISE-DEBIT-DTL].REFERENCE = dbo.[RE-TENANCY].[TENANCY-REF] INNER JOIN
                         dbo.[IH-PLACE-CHG] ON substring(dbo.[RE-TENANCY].[TENANCY-REF],1,10) = dbo.[IH-PLACE-CHG].[PLACE-REF]


) AS HBfile order by cast(HBfile.[0] as bigint), HBfile.[6] desc

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM