【问题标题】:Merging two tables with interleaving the result of select queries of both tables in a proportion合并两个表并按比例交错两个表的选择查询结果
【发布时间】:2020-04-12 18:22:32
【问题描述】:

我有两张桌子

CREATE TABLE Posts
(
Id BIGSERIAL NOT NULL,
Content TEXT NOT NULL
);

CREATE TABLE Ads
(
Id BIGSERIAL NOT NULL,
Content TEXT NOT NULL
);

我需要将这两个表按比例组合起来,应用ORDER BYOFFSET1 行来自Ads 表中的每个10 行来自Posts 表有什么办法可以做到这一点吗?。

最后一行应该是 10 个帖子 - 1 个广告 - 10 个帖子 - 1 个广告。如何通过交错不同选择的结果来实现两张表的合并

普通UNION 将合并所有行而不交错

SELECT * FROM (SELECT Id, Content, 'Post' AS Type FROM Posts
UNION 
SELECT Id, Content, 'Ads' AS Type FROM Ads) AS sel
LIMIT 10;

【问题讨论】:

    标签: sql postgresql sql-order-by union


    【解决方案1】:

    一种选择是使用row_number()

    select id, content, type
    from (
        select id, content, 'post' type, (row_number() over(order by id) - 1) / 10 rn 
        from posts
        union all select id, content, 'ads', row_number() over(order by id) - 1 
        from ads
    )
    where rn <= 1
    order by rn, type desc
    

    诀窍是将posts 表的行号除以 10 - 因此每组 10 行连续获得相同的排名。然后,外部查询按等级排序,然后按降序类型。这会将前 10 个帖子放在首位(排名为 0),然后是 1 个广告,依此类推。排名也可以用来限制组的数量。

    【讨论】:

    • 条件rn &lt;= 1的目的是什么?因为在这种情况下,查询最多只返回 20 行。
    • @Farshan:我知道你只想要两个组(10 个帖子,1 个广告,10 个帖子,1 个广告)。如果您想要所有组,则只需删除该条件即可。
    • 抱歉误导您。你的回答对我有用。谢谢你:)
    • 只是一个查询,如果posts表中没有更多记录要合并,我不想将剩余的广告作为列表的最后一行?
    • 为了回答我上面的查询,我只是在 cte 中使用了上面的查询并添加了条件rn &lt;= (select max(rn) from cte where type = 'post')
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-19
    • 2011-04-05
    • 1970-01-01
    • 2022-06-16
    • 2016-10-27
    • 1970-01-01
    相关资源
    最近更新 更多