SQL Server 2014:如何在 csv 导出中包含 header 和详细信息
SQL Server 2014: How to include header and detail in csv export
我正在尝试生成一个脚本来导出 csv 文件以显示 header 记录和相应的详细记录。
例如,输出需要是
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
我尝试使用下面的 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
但是此代码错误地生成了以下结果:
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
任何想法,感谢帮助。
谢谢
使用 WHERE 子句过滤掉不需要的 header 行。合意性似乎基于结果中的第一个日期列。
正在尝试找出问题所在
由于重复出现在 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]
此查询包含 2 个内部联接,这意味着如果联接不是在 1-1 关系上进行的,则生成的行数可能多于源计数。
检查您提供的输出后:
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
除了使用此命令生成的第四列外,所有 header 列都相同:
format(dbo.[IH-PLACE-CHG].[START-DATE], 'dd.MM.yyyy') AS [2]
解决方案
如果您只需要第一个值,那么您可以使用 First_Value()
window 函数:
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]
并且您可以在 headers 查询中添加不同的运算符,整个 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
我正在尝试生成一个脚本来导出 csv 文件以显示 header 记录和相应的详细记录。
例如,输出需要是
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
我尝试使用下面的 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
但是此代码错误地生成了以下结果:
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
任何想法,感谢帮助。 谢谢
使用 WHERE 子句过滤掉不需要的 header 行。合意性似乎基于结果中的第一个日期列。
正在尝试找出问题所在
由于重复出现在 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]
此查询包含 2 个内部联接,这意味着如果联接不是在 1-1 关系上进行的,则生成的行数可能多于源计数。
检查您提供的输出后:
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
除了使用此命令生成的第四列外,所有 header 列都相同:
format(dbo.[IH-PLACE-CHG].[START-DATE], 'dd.MM.yyyy') AS [2]
解决方案
如果您只需要第一个值,那么您可以使用 First_Value()
window 函数:
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]
并且您可以在 headers 查询中添加不同的运算符,整个 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