按照规则3、2、1从每个表中合并Select
查询中的三个表,如下所示:
TableC:ID,FieldA,FieldB,FieldC,....
ID
:每个表中的自动编号
FieldA
在所有三个表中都是唯一的。我正在寻找一个Select
查询来合并三个表,如下所示:
TableA
中按ID排序的前三条记录TableB
中按ID排序的前两个记录TableC
中的前1条记录,按ID排序重复此操作,直到从所有三个表中选择所有记录。
如果某个表的记录较少或不符合条件,请忽略该记录并继续其他记录。
我的尝试
我完全通过编程方式做到了这一点,例如SQL Server存储过程中的游标和If
条件。
这会造成延迟。
答案 0 :(得分:0)
这里没有很多信息,但是我假设您可以使用UNION组合多个语句。
SELECT * TableA ORDER BY ID DESC OFFSET 3 ROWS
UNION
SELECT * TableB ORDER BY ID DESC OFFSET 2 ROWS
UNION
SELECT * TableC ORDER BY ID DESC OFFSET 1 ROWS
执行,看看是否可行。
/ AF
答案 1 :(得分:0)
这需要一个公式,该公式从每个表中获取行号,并将其转换为跳过所需值的一系列整数。
在下面的查询中,为了缩短公式,我添加了一些CTE。真正的魔力在UNION
中。另外,我为您的控件添加了一个附加字段。随时摆脱它。
WITH A_Aux as (
SELECT 'A' As FromTable, ROW_NUMBER() OVER (ORDER BY ID) AS RowNum, TableA.*
FROM TableA
), B_Aux AS (
SELECT 'B' As FromTable, ROW_NUMBER() OVER (ORDER BY ID) AS RowNum, TableB.*
FROM TableB
), C_Aux AS (
SELECT 'C' As FromTable, ROW_NUMBER() OVER (Order BY ID) AS RowNum, TableC.*
FROM TableC
)
SELECT *
FROM (
SELECT RowNum+3*FLOOR((RowNum-1)/3) As ColumnForOrder, A_Aux.* FROM A_Aux
UNION ALL
SELECT 3+RowNum+4*FLOOR((RowNum-1)/2), B_Aux.* FROM B_Aux
UNION ALL
SELECT 6*RowNum, C_Aux.* FROM C_Aux
) T
ORDER BY ColumnForOrder
PS:请注意模式Offset + RowNum + (6-N) * Floor((RowNum-1)/N)
将N个记录分组在一起(当然,TableC
简化了很多)。
PPS:我没有可用的SQL Server对其进行测试。让我知道是否存在语法错误。
答案 2 :(得分:0)
据我了解,我创建了三个临时表ta,tb和tc。
select * into #ta from (
select 'A' a
union all
select 'A' a
union all
select 'A' a
union all
select 'A' a
union all
select 'A' a
union all
select 'A' a
union all
select 'A' a
) a
select * into #tb from (
select 'B' b
union all
select 'B'
union all
select 'B'
union all
select 'B'
union all
select 'B'
) b
select * into #tc from (
select 'C' c
union all
select 'C'
union all
select 'C'
union all
select 'C'
union all
select 'C'
) c
如果表与您的表匹配,则输出看起来像A,A,A,B,B,C,A,A,A,B,B,C,A,B,C,C,C
T-SQL
declare @TAC int = (select count (*) from #ta) -- Table A Count = 7
declare @TBC int = (select count (*) from #tb) -- Table B Count = 5
declare @TAR int = @TAC % 3 -- Table A Reminder = 1
declare @TBR int = @TBC % 2 -- Table B Reminder = 1
declare @TAQ int = (@TAC - @TAR) / 3 -- Table A Quotient = (7 - 1) / 3 = 2, is will passed on NTILE
-- So we gonna split as two group (111), (222)
declare @TBQ int = (@TBC - @TBR) / 2 -- Table B Quotient = (5 - 1) / 2 = 2, is will passed on NTILE
-- So we gonna split as two group (11), (22)
select * from (
select *, NTILE (@TAQ) over ( order by a) FirstOrder, 1 SecondOrder from (
select top (@TAC - @TAR) * from #ta order by a
) ta -- 6 rows are obtained out of 7.
union all
select *, @TAQ + 1, 1 from (
select top (@TAR) * from #ta order by a desc
) ta -- Remaining one row is obtained. Order by desc is must
-- Here FirstOrder is next value of previous value.
union all
select *, NTILE (@TBQ) over ( order by b), 2 from (
select top (@TBC - @TBR) * from #tb order by b
) tb
union all
select *, @TBQ + 1, 2 from (
select top (@TBR) * from #tb order by b desc
) tb
union all
select *, ROW_NUMBER () over (order by c), 3 from #tc
) abc order by FirstOrder, SecondOrder
让我解释一下T-SQL: 在此之前,FYR:NTILE和Row Number
注意:
order by <yourcolumn>
中的列。