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

时间:2015-06-01 08:42:11

标签: sql tsql sql-server-2012 sequence

是否可以创建一个交错的序列,其中第一个和最后一个值依次转换,直到数据集为空而不使用连接和用户定义的函数或过程?

  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 个答案:

答案 0 :(得分:1)

这个想法是生成两个序列:

  1. 行号为1,3,5,......
  2. 的升序项目
  3. 行号为2,4,6,......的降序项目
  4. 然后,我们只需要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
    

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