从2个表中选择行,其中前5行来自一个表,然后是来自第二个表的1

时间:2015-10-20 07:00:51

标签: sql sql-server stored-procedures

我在SQL数据库中有2个表。

SELECT name from table1 ORDER BY name
SELECT name from table2 ORDER BY name

我想创建一个带有union select的存储过程,它创建一个带有以下输出的表 - table1中的5行和table2中的1行,table1中的5行和table2中的1行等:

row 1 from table1
row 2 from table1
row 3 from table1
row 4 from table1
row 5 from table1
row 6 from table2
row 7 from table1
row 8 from table1
row 9 from table1
row 10 from table1
row 11 from table1
row 12 from table2
etc

这可能吗?如果是的话有什么提示吗? 感谢

3 个答案:

答案 0 :(得分:1)

使用ROW_NUMBER和一些数学:

WITH Cte AS(
    SELECT name,
        rn = ROW_NUMBER() OVER(ORDER BY name) + ((ROW_NUMBER() OVER(ORDER BY name) - 1) / 5)
    FROM table1
    UNION ALL
    SELECT name,
        rn = ROW_NUMBER() OVER(ORDER BY name) * 6
    FROM table2
)
SELECT name FROM Cte ORDER BY rn

以上内容将显示table中的5行,然后显示table2中的1行,依此类推。

SQL Fiddle

答案 1 :(得分:0)

你可以尝试这样的事情:

Select x='1', n, n%5,  id, name From (
    Select id, name 
        , n = ROW_NUMBER() over(order by ID)        
    From T1
) as Q1
Where (n % 6) <> 0
Union All
Select '2', n, n%5, id, name From (
    Select id, name 
        , n = ROW_NUMBER() over(order by ID)        
    From T2
) as Q2
Where (n % 6) = 0
Order By id

如果您的表格中已有没有间隙的订单ID,则您很可能不需要使用ROW_NUMBER()来创建有序ID。

您可以查看此示例:SQL Fiddle

使用Modulo 6(%6),您将获得0到6之间的值=&gt; 6%6 = 12%6 = 0

答案 2 :(得分:0)

您可以为两个表使用临时表(或添加列),并使用一个名为“GroupId INT”的列。

create #temp ( groupId int, tbl int, name nvarchar(...))

对于table1,使用CONVERT(INT,ROW_NUMBER()/ 5)填充此列 对于table2,请使用ROW_NUMBER()

填充此列
insert into #temp ( groupId, tbl, name)
  select CONVERT(INT, ROW_NUMBER() / 5.0), 1, name from table1 order by name

insert into #temp ( groupId, tbl, name)
  select ROW_NUMBER(), 2, name from table2 order by name

然后使用

SELECT name 
from #temp    
ORDER BY groupId, tbl, name

注意:使用临时表可以避免使用CTE我认为