如何在数据的每个 "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

this SQLFiddle

这个对你有用吗?

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