获取sqlserver表中所有行的行条目子集的排列

时间:2017-07-14 20:37:16

标签: sql sql-server

说我有这样一张桌子:

Order By veh("VIN").ToString() Ascending

我希望在表中添加行,这些行具有现有行的列子集(a1,a2,a3)的排列。例如。 row1会贡献额外的行,如:

idx  | a1 | a2 | a3 | b1 | c1
-----------------------------
idx1, a11, a12, a13, b11, c11
idx2, a21, a22, a23, b21, c21
idx3, a31, a32, a33, b31, c31
idx4, a41, a42, a43, b41, c41

我将如何在sqlserver中执行此操作?感谢

3 个答案:

答案 0 :(得分:0)

这是一种交叉连接方法。

declare @table table (indx varchar(4), a1 varchar(3), a2 varchar(3), a3 varchar(3), b1 varchar(3), c1 varchar(3))
insert into @table
values
('idx1','a11','a12','a13','b11','c11'),
('idx2','a21','a22','a23','b21','c21')

;with cte as(
    select indx, a1
    from @table
    union
    select indx, a2
    from @table
    union 
    select indx, a3
    from @table)

select distinct
    c1.indx
    ,c1.a1
    ,c2.a1 as a2
    ,c3.a1 as a3
    ,t.b1
    ,t.c1
from cte c1
    cross join cte c2
    cross join cte c3
    left join @table t on t.indx = c1.indx
where 
    c1.indx = c2.indx  
    and c3.indx = c1.indx
    and c1.a1 <> c2.a1
    and c1.a1 <> c3.a1
    and c2.a1 <> c3.a1
order by
    c1.indx
    ,c1.a1
    ,c2.a1
    ,c3.a1

<强>返回

+------+-----+-----+-----+-----+-----+
| indx | a1  | a2  | a3  | b1  | c1  |
+------+-----+-----+-----+-----+-----+
| idx1 | a11 | a12 | a13 | b11 | c11 |
| idx1 | a11 | a13 | a12 | b11 | c11 |
| idx1 | a12 | a11 | a13 | b11 | c11 |
| idx1 | a12 | a13 | a11 | b11 | c11 |
| idx1 | a13 | a11 | a12 | b11 | c11 |
| idx1 | a13 | a12 | a11 | b11 | c11 |
| idx2 | a21 | a22 | a23 | b21 | c21 |
| idx2 | a21 | a23 | a22 | b21 | c21 |
| idx2 | a22 | a21 | a23 | b21 | c21 |
| idx2 | a22 | a23 | a21 | b21 | c21 |
| idx2 | a23 | a21 | a22 | b21 | c21 |
| idx2 | a23 | a22 | a21 | b21 | c21 |
+------+-----+-----+-----+-----+-----+

答案 1 :(得分:0)

排列,5!每个idx的组合提供了源行中的所有值都不同。

declare @t table(
    idx  varchar(10)
    , a1 varchar(10)
    , a2 varchar(10)
    , a3 varchar(10)
    , b1 varchar(10)
    , c1 varchar(10)
    );
insert @t 
values
 ('idx1','a11','a12','a13','b11','c11')
,('idx2','a21','a22','a23','b21','c21')
,('idx3','a31','a32','a33','b31','c31')
,('idx4','a41','a42','a43','b41','c41');

with pvt as (
    select idx,m 
    from @t
    cross apply ( 
         values(a1),(a2),(a3),(b1),(c1)
         ) vals(m)
)

select t1.idx, t1.m, t2.m, t3.m, t4.m, t5.m
from pvt t1
join pvt t2 on t1.idx=t2.idx and t2.m not in (t1.m)
join pvt t3 on t1.idx=t3.idx and t3.m not in (t1.m, t2.m)
join pvt t4 on t1.idx=t4.idx and t4.m not in (t1.m, t2.m, t3.m)
join pvt t5 on t1.idx=t5.idx and t5.m not in (t1.m, t2.m, t3.m, t4.m)
order by t1.idx, t1.m, t2.m, t3.m, t4.m, t5.m;

答案 2 :(得分:-1)

你尝试过类似的东西吗?关于a1,a2,a3列的唯一性和内容,你的问题非常模糊。

WITH cte AS (
  SELECT Idx, b1, c1, a1 AS a
  UNION
  SELECT Idx, b1, c1, a2 AS a
  UNION
  SELECT Idx, b1, c1, a3 AS a
)
SELECT cte1.Idx, cte1.b1, cte1.c1, cte1.a AS a1, cte2.a AS a2, cte3.a AS a3
FROM cte AS cte1
  JOIN cte AS cte2 ON cte1.Idx = cte2.Idx AND cte1.b1 = cte2.b1 AND cte1.c1 = cte2.c1
  JOIN cte AS cte3 ON cte1.Idx = cte3.Idx AND cte1.b1 = cte3.b1 AND cte1.c1 = cte3.c1