【问题标题】:Select rows from 2 tables where the first 5 rows come from one table then 1 from the second table从 2 个表中选择行,其中前 5 行来自一个表,然后 1 行来自第二个表
【发布时间】:2016-01-18 17:18:40
【问题描述】:

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

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

我想创建一个带有联合选择的存储过程,该过程创建一个具有以下输出的表 - 来自 table1 的五行和来自 table2 的一行,然后来自 table1 的 5 行和来自 table2 的一行等:

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

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

【问题讨论】:

  • 为什么不在你的存储过程中有两个游标?
  • 你能分享 t1 和 t2 的表模型和样本数据吗?您如何知道表格中哪一行是 #1 或 #5 以及它们的顺序是什么?

标签: sql sql-server stored-procedures


【解决方案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

【讨论】:

  • 感谢您的解决方案。对我来说这听起来可行,所以我会对其进行测试并随时通知您。
【解决方案2】:

你可以试试这样的:

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

使用模 6 (%6),您将获得 0 到 6 => 6%6 = 12%6 = 0 的值

【讨论】:

    【解决方案3】:

    您可以为两个表使用一个临时表(或添加一个列),其中包含一个名为“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 可以避免使用临时表

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多