没有连接操作或用户定义对象的 TSQL 交错序列

TSQL Interleaved sequence without join operations or user defined objects

是否可以在不使用连接和用户定义的函数或过程的情况下创建一个第一个值和最后一个值依次出现直到数据集为空的交错序列?

  code  type    model   price
    1   Hats    1298    700,00
    1   Shoes   1232    600,00
    1   Pants   1276    400,00
    2   Hats    1321    970,00
    2   Shoes   1121    850,00
    2   Pants   1433    270,00
    3   Hats    1750    1200,00
    3   Shoes   1233    600,00
    3   Pants   1434    290,00
    4   Hats    1298    1050,00
    4   Shoes   1121    850,00
    4   Pants   1401    150,00
    5   Hats    1752    1150,00
    5   Shoes   1121    850,00
    5   Pants   1408    270,00
    6   Hats    1298    950,00
    6   Shoes   1233    950,00
    6   Pants   1288    400,00
    7   Shoes   1232    400,00
    8   Shoes   1232    350,00
    9   Shoes   1232    350,00
    10  Shoes   1260    350,00
    11  Shoes   1233    980,00
    12  Shoes   1233    970,00

我在行之间添加了额外的空格以获得交错序列的想法。

您想从最低编码项 (asc) 获得奇数值,从最高编码项 (desc) 获得偶数值。您还想按帽子、鞋子和裤子订购类型。

code type   model   price
1   Hats    1298    700,00
1   Shoes   1232    600,00
1   Pants   1276    400,00

6   Hats    1298    950,00
12  Shoes   1233    970,00
6   Pants   1288    400,00

2   Hats    1321    970,00
2   Shoes   1121    850,00
2   Pants   1433    270,00

5   Hats    1752    1150,00
11  Shoes   1233    980,00
5   Pants   1408    270,00

3   Hats    1750    1200,00
3   Shoes   1233    600,00
3   Pants   1434    290,00

4   Hats    1298    1050,00
10  Shoes   1260    350,00
4   Pants   1401    150,00

4   Shoes   1121    850,00

9   Shoes   1232    350,00

5   Shoes   1121    850,00

8   Shoes   1232    350,00

6   Shoes   1233    950,00

7   Shoes   1232    400,00

现在我想到了包含连接的解决方案,但我正在寻找无需使用它也能工作的解决方案。

我使用连接的解决方案:

with cteasc as 
(
    select
    ROW_NUMBER() over(order by code,charindex(type, 'HatsShoesPants'))id
    ,(ROW_NUMBER() over(partition by type order by code,charindex(type, 'HatsShoesPants')) + 1) / 2 offsetasc
    ,code,model,price,type 
    from mydata
),
ctedsc as 
(
    select
    ROW_NUMBER() over (partition by type order by code desc)id
    ,code,model,price,type
    from cteasc
)
select t1.id
,case
    when t1.code%2=1
    then LAG(t1.type,t1.code-t1.offsetasc,t1.type)over(partition by t1.type order by t1.id)
    else LAG(t2.type,t1.code-t1.offsetasc,t1.type)over(partition by t1.type order by t1.id)
end type
,case
    when t1.code%2=1
    then LAG(t1.model,t1.code-t1.offsetasc,t1.model)over(partition by t1.type order by t1.id)
    else LAG(t2.model,t1.code-t1.offsetasc,t1.model)over(partition by t1.type order by t1.id)
end model
,case
    when t1.code%2=1
    then LAG(t1.price,t1.code-t1.offsetasc,t1.price)over(partition by t1.type order by t1.id)
    else LAG(t2.price,t1.code-t1.offsetasc,t1.price)over(partition by t1.type order by t1.id)
end price 
from
cteasc t1
join ctedsc t2
on t1.code = t2.id
and t1.type = t2.type

我们的想法是生成两个序列:

  1. 行号为 1、3、5 的升序项...
  2. 行号为 2、4、6 的降序项...

然后,我们只需要 UNION ALL 序列并对它们进行排序。

with ascItems as (
    select *, row_number() over (order by someCol ASC) r * 2 - 1 as r from T
)
, descItems as (
    select *, row_number() over (order by someCol DESC) r * 2 as r from T
)
select * from ascItems
union all
select * from descItems
order by r

这应该要求 table T 可以排序两次(按索引或按 2xsorting)。 UNION ALL 应该表现为廉价的合并连接。