SQL Server 动态 CTE 行

Posted

技术标签:

【中文标题】SQL Server 动态 CTE 行【英文标题】:SQL Server dynamic CTE rows 【发布时间】:2021-11-27 04:28:21 【问题描述】:

我想得到如下结果

seqno seqno_ups_desc  
--------------------
108 108A  
108 108B  
108 108C  
108 108D  
109 109A  
109 109B  
109 109C  
109 109D  
110 110A  
110 110B  
110 110C  
110 110D  
111 111A  
111 111B  
111 111C  
111 111D  

我目前有这样的结果,但我无法将其增加到 109 及以上

seqno seqno_ups_desc  
--------------------
108 A  
108 B  
108 C  
108 D  

这是我的代码

DECLARE @OrderID INT = 215332, @MCHID INT = 188, @bbs_ups INT

SET @bbs_ups = 4

;WITH CreateBundleSticker([counter], bundle_seqno, bundle_seqno_ups) AS 
(
    SELECT 
        1 counter, 
        ISNULL((SELECT TOP 1 bbd_bundle_seqno 
                FROM BAG_BundleStickerDetails 
                WHERE bbd_order_id_fk = @OrderID 
                  AND bbd_mch_id_fk = @MCHID 
                  AND bbd_status = 'A' 
                ORDER BY bbd_id DESC), 0), CHAR(ASCII('A')) [char]
    UNION ALL

    SELECT
        [counter] + 1, bundle_seqno, 
        CHAR(ASCII(bundle_seqno_ups) + 1)
    FROM
        CreateBundleSticker
    WHERE
        [counter] < @bbs_ups
)
SELECT * 
FROM CreateBundleSticker

【问题讨论】:

为数字制作一个 cte(有很多可用的示例),为字母制作一个 cte(可能只是 4 个值的并集),然后将两者交叉连接。 你能描述一下你的最终目标是什么吗?我猜你想为每个 seq_no 生成字符以及直到 D 的 seq_no @GeorgeJoseph 嗨,你是对的,我的最终目标是达到 seq_no 直到 D,seq_no 可以达到 100000 或更多 【参考方案1】:
WITH
  numbers(id) AS
(
              SELECT 0
    UNION ALL SELECT 1
    UNION ALL SELECT 2
    UNION ALL SELECT 3
),
  letters(id, val) AS
(
  SELECT
    id,
    CHAR(ASCII('A') + id)
  FROM
    numbers
),
  sequence_base AS
(
  SELECT TOP 1
    bbd_bundle_seqno
  FROM
    BAG_BundleStickerDetails
  WHERE
        bbd_order_id_fk = @OrderID
    AND bbd_mch_id_fk = @MCHID
    AND bbd_status = 'A'
  ORDER BY
    bbd_id DESC
)
SELECT
  ISNULL(sequence_base.bbd_bundle_seqno, 1) + numbers.id,
  letters.val
FROM
  numbers
CROSS JOIN
  letters
LEFT JOIN
  sequence_base
    ON 1=1

【讨论】:

【参考方案2】:
DECLARE @OrderID INT = 215332, @MCHID INT = 188, @bbs_ups INT

SET @bbs_ups = 4

;WITH CreateBundleSticker([counter], bundle_seqno, bundle_seqno_ups) AS
(
    SELECT 
        1 counter,
        ISNULL((SELECT TOP 1 bbd_bundle_seqno
                FROM BAG_BundleStickerDetails
                WHERE bbd_order_id_fk = @OrderID
                  AND bbd_mch_id_fk = @MCHID
                  AND bbd_status = 'A'
                ORDER BY bbd_id DESC), 0), CHAR(ASCII('A')) [char]
    UNION ALL

    SELECT
        [counter] + 1, bundle_seqno, 
        CHAR(ASCII(bundle_seqno_ups) + 1)
    FROM
        CreateBundleSticker
    WHERE
        [counter] < @bbs_ups

)
SELECT bbd_bundle_seqno+' '+bbd_bundle_seqno+' '+bundle_seqno_ups AS Result
FROM BAG_BundleStickerDetails bsd,CreateBundleSticker cbs
GROUP BY bbd_bundle_seqno,bundle_seqno_ups

【讨论】:

正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于SQL Server 动态 CTE 行的主要内容,如果未能解决你的问题,请参考以下文章

用于动态查找表、DB2 或 SQL Server 的紧凑 CTE 语法

ANSI sql将行动态转换为列数据

sql server中的cte

SQL Server 公用表表达式(CTE)实现递归

SQL Server 公用表表达式(CTE)实现递归

SQL Server CTE 递归查询全解