如何在数据的每个 "category" 更改之间向我的 SQL 结果添加一行?
How can I add a row to my SQL results between each "category" change in the data?
我使用 SQL Server 2019 生成一长串运输选项。该列表是通过对包含列表项的 table 进行简单查询而生成的,并显示在手持终端上。用户发现浏览列表以找到正确的选项既麻烦又费时,而且每天必须这样做几次。
我想做的是在列表中添加一个带有几个破折号的类别名称,然后将其显示在手持终端上。这将显示为某种“分页符”,这将使他们能够快速浏览列表。
这里的挑战是终端软件非常基础,无法修改。它只能做一件事,即执行“GetList”存储过程并按顺序从该过程中读取每一行,以创建列表,然后将其显示给用户。
输出必须是单个 varchar 列,宽度不超过 64 个字符,所以我能做的非常有限。
我可以修改存储过程使用的数据 table 和查询,我已经成功地添加了 CategoryRank 和 ColumnRank 列并使用它们来更改列表显示的顺序对用户更有意义。
例如,
当前查询:
SELECT ListItem
FROM SymbolScanner.dbo.ShippingTypes WITH(NOLOCK))
ORDER BY CategoryRank,
ColumnRank
运输类型table:
ListItem varchar(64) NOT NULL PRIMARY KEY CLUSTERED,
Category varchar(100) NOT NULL,
CategoryRank int NOT NULL,
ColumnRank int NOT NULL
示例数据(真实列表有数百项):
ListItem Category CategoryRank ColumnRank
RM 1st Class No Tracking Royal Mail 1 1
RM 1st Class Tracked Royal Mail 1 2
RM 2nd Class No Tracking Royal Mail 1 3
RM 2nd Class Tracked Royal Mail 1 4
TNT 24 Hour Tracked TNT 2 1
TNT 24 Hour No Tracking TNT 2 2
TNT 48 Hour Tracked TNT 2 3
TNT 48 Hour no Tracking TNT 2 4
DHL 24 Hour Tracked DHL 3 1
DHL 48 Hour Tracked DHL 3 1
当前输出:
RM 1st Class No Tracking
RM 1st Class Tracked
RM 2nd Class No Tracking
RM 2nd Class Tracked
TNT 24 Hour Tracked
TNT 24 Hour No Tracking
TNT 48 Hour Tracked
TNT 48 Hour No Tracking
DHL 24 Hour Tracked
DHL 48 Hour Tracked
结果只是一个 varchar 列表,按照我希望的方式排序。这很好,但我想在包括类别名称的每个类别之间添加一个视觉中断,以便用户更容易快速向下滚动并查看类别何时更改。
期望的输出:
---- Royal Mail ----
RM 1st Class No Tracking
RM 1st Class Tracked
RM 2nd Class No Tracking
RM 2nd Class Tracked
---- TNT ----
TNT 24 Hour Tracked
TNT 24 Hour No Tracking
TNT 48 Hour Tracked
TNT 48 Hour No Tracking
---- DHL ----
DHL 24 Hour Tracked
DHL 48 Hour Tracked
因此,我需要在每次更改类别之前在我的结果中插入一个额外的行,其中包括类别名称和一些短划线字符。我敢肯定有一些 SQL 体操可以做到这一点,我什至不知道从哪里开始。
SQL 数据库旨在处理数据,而不是格式化数据。通常,这将由查询数据并准备结果以供查看的中间件处理,但您似乎没有。
您可以在第二个查询中创建 header 行并通过 UNIONing 合并结果:
SELECT ListItem FROM
(
SELECT ListItem, CategoryRank, ColumnRank
FROM ShippingTypes
UNION ALL
SELECT '---- ' + Category + ' ----', CategoryRank, 0
FROM ShippingTypes
GROUP BY Category, CategoryRank
) sub
ORDER BY CategoryRank,
ColumnRank
这个对你有用吗?
WITH
-- your input ...
indata(listitem,category,categoryrank,columnrank) AS (
SELECT 'RM 1st Class No Tracking','Royal Mail',1,1
UNION ALL SELECT 'RM 1st Class Tracked','Royal Mail',1,2
UNION ALL SELECT 'RM 2nd Class No Tracking','Royal Mail',1,3
UNION ALL SELECT 'RM 2nd Class Tracked','Royal Mail',1,4
UNION ALL SELECT 'TNT 24 Hour Tracked','TNT',2,1
UNION ALL SELECT 'TNT 24 Hour No Tracking','TNT',2,2
UNION ALL SELECT 'TNT 48 Hour Tracked','TNT',2,3
UNION ALL SELECT 'TNT 48 Hour no Tracking','TNT',2,4
UNION ALL SELECT 'DHL 24 Hour Tracked','DHL',3,1
UNION ALL SELECT 'DHL 48 Hour Tracked','DHL',3,1
)
-- end of your input. Real query starts here,
-- and replace the comma below with "WITH"
,
the_union(category,listitem) AS (
SELECT DISTINCT
category
, '------ '||category||' -----'
FROM indata
UNION ALL SELECT
category
, listitem
FROM indata
)
SELECT
listitem
FROM the_union
ORDER BY
category
, listitem
;
-- out listitem
-- out --------------------------
-- out ------ DHL -----
-- out DHL 24 Hour Tracked
-- out DHL 48 Hour Tracked
-- out ------ Royal Mail -----
-- out RM 1st Class No Tracking
-- out RM 1st Class Tracked
-- out RM 2nd Class No Tracking
-- out RM 2nd Class Tracked
-- out ------ TNT -----
-- out TNT 24 Hour No Tracking
-- out TNT 24 Hour Tracked
-- out TNT 48 Hour Tracked
-- out TNT 48 Hour no Tracking
我使用 SQL Server 2019 生成一长串运输选项。该列表是通过对包含列表项的 table 进行简单查询而生成的,并显示在手持终端上。用户发现浏览列表以找到正确的选项既麻烦又费时,而且每天必须这样做几次。
我想做的是在列表中添加一个带有几个破折号的类别名称,然后将其显示在手持终端上。这将显示为某种“分页符”,这将使他们能够快速浏览列表。
这里的挑战是终端软件非常基础,无法修改。它只能做一件事,即执行“GetList”存储过程并按顺序从该过程中读取每一行,以创建列表,然后将其显示给用户。
输出必须是单个 varchar 列,宽度不超过 64 个字符,所以我能做的非常有限。
我可以修改存储过程使用的数据 table 和查询,我已经成功地添加了 CategoryRank 和 ColumnRank 列并使用它们来更改列表显示的顺序对用户更有意义。
例如,
当前查询:
SELECT ListItem
FROM SymbolScanner.dbo.ShippingTypes WITH(NOLOCK))
ORDER BY CategoryRank,
ColumnRank
运输类型table:
ListItem varchar(64) NOT NULL PRIMARY KEY CLUSTERED,
Category varchar(100) NOT NULL,
CategoryRank int NOT NULL,
ColumnRank int NOT NULL
示例数据(真实列表有数百项):
ListItem Category CategoryRank ColumnRank
RM 1st Class No Tracking Royal Mail 1 1
RM 1st Class Tracked Royal Mail 1 2
RM 2nd Class No Tracking Royal Mail 1 3
RM 2nd Class Tracked Royal Mail 1 4
TNT 24 Hour Tracked TNT 2 1
TNT 24 Hour No Tracking TNT 2 2
TNT 48 Hour Tracked TNT 2 3
TNT 48 Hour no Tracking TNT 2 4
DHL 24 Hour Tracked DHL 3 1
DHL 48 Hour Tracked DHL 3 1
当前输出:
RM 1st Class No Tracking
RM 1st Class Tracked
RM 2nd Class No Tracking
RM 2nd Class Tracked
TNT 24 Hour Tracked
TNT 24 Hour No Tracking
TNT 48 Hour Tracked
TNT 48 Hour No Tracking
DHL 24 Hour Tracked
DHL 48 Hour Tracked
结果只是一个 varchar 列表,按照我希望的方式排序。这很好,但我想在包括类别名称的每个类别之间添加一个视觉中断,以便用户更容易快速向下滚动并查看类别何时更改。
期望的输出:
---- Royal Mail ----
RM 1st Class No Tracking
RM 1st Class Tracked
RM 2nd Class No Tracking
RM 2nd Class Tracked
---- TNT ----
TNT 24 Hour Tracked
TNT 24 Hour No Tracking
TNT 48 Hour Tracked
TNT 48 Hour No Tracking
---- DHL ----
DHL 24 Hour Tracked
DHL 48 Hour Tracked
因此,我需要在每次更改类别之前在我的结果中插入一个额外的行,其中包括类别名称和一些短划线字符。我敢肯定有一些 SQL 体操可以做到这一点,我什至不知道从哪里开始。
SQL 数据库旨在处理数据,而不是格式化数据。通常,这将由查询数据并准备结果以供查看的中间件处理,但您似乎没有。
您可以在第二个查询中创建 header 行并通过 UNIONing 合并结果:
SELECT ListItem FROM
(
SELECT ListItem, CategoryRank, ColumnRank
FROM ShippingTypes
UNION ALL
SELECT '---- ' + Category + ' ----', CategoryRank, 0
FROM ShippingTypes
GROUP BY Category, CategoryRank
) sub
ORDER BY CategoryRank,
ColumnRank
这个对你有用吗?
WITH
-- your input ...
indata(listitem,category,categoryrank,columnrank) AS (
SELECT 'RM 1st Class No Tracking','Royal Mail',1,1
UNION ALL SELECT 'RM 1st Class Tracked','Royal Mail',1,2
UNION ALL SELECT 'RM 2nd Class No Tracking','Royal Mail',1,3
UNION ALL SELECT 'RM 2nd Class Tracked','Royal Mail',1,4
UNION ALL SELECT 'TNT 24 Hour Tracked','TNT',2,1
UNION ALL SELECT 'TNT 24 Hour No Tracking','TNT',2,2
UNION ALL SELECT 'TNT 48 Hour Tracked','TNT',2,3
UNION ALL SELECT 'TNT 48 Hour no Tracking','TNT',2,4
UNION ALL SELECT 'DHL 24 Hour Tracked','DHL',3,1
UNION ALL SELECT 'DHL 48 Hour Tracked','DHL',3,1
)
-- end of your input. Real query starts here,
-- and replace the comma below with "WITH"
,
the_union(category,listitem) AS (
SELECT DISTINCT
category
, '------ '||category||' -----'
FROM indata
UNION ALL SELECT
category
, listitem
FROM indata
)
SELECT
listitem
FROM the_union
ORDER BY
category
, listitem
;
-- out listitem
-- out --------------------------
-- out ------ DHL -----
-- out DHL 24 Hour Tracked
-- out DHL 48 Hour Tracked
-- out ------ Royal Mail -----
-- out RM 1st Class No Tracking
-- out RM 1st Class Tracked
-- out RM 2nd Class No Tracking
-- out RM 2nd Class Tracked
-- out ------ TNT -----
-- out TNT 24 Hour No Tracking
-- out TNT 24 Hour Tracked
-- out TNT 48 Hour Tracked
-- out TNT 48 Hour no Tracking