以循环方式分配记录

问题描述 投票:0回答:1

我有一个以循环赛方式获得记录的场景。我的桌子与下面类似

账户 电子邮件 排名 国家
账户_A abc@account_a.com 1 美国
账户_A cde@account_a.com 2 美国
账户_A fgh@account_a.com 3 美国
账户_A klh@account_a.com 4 美国
账户_B abc@account_b.com 1 日本
账户_C xyz@account_c.com 1 印度
账户_C pqr@account_c.com 2 印度
账户_D efg@account_d.com 1 中国
账户_D xyz@account_d.com 2 中国
账户_E abc@account_E.com 1 日本

预期输出:每次运行我只需要带 8 条记录。我必须每次计数时至少带一封电子邮件。有些帐户可能有超过 100 条记录,而有些帐户只有 1 条记录。正如您可以看到下面的示例输出 - 从 A 到 E 的每个帐户有一个联系人(总共 5 个),然后我需要从 Rank 级别 2 带来一条附加记录`(A、C 和 D)

账户 电子邮件 国家
账户_A abc@account_a.com 美国
账户_A cde@account_a.com 美国
账户_B abc@account_b.com 日本
账户_C xyz@account_c.com 印度
账户_C pqr@account_c.com 印度
账户_D efg@account_c.com 中国
账户_D xyz@account_d.com 中国
账户_E abc@account_e.com 日本

我不知道如何为此构建查询。有一种方法我们可以在 PL/SQL 中使用 for 循环语句来做到这一点,但我需要通过 SQL 查询来实现这一点

mysql oracle hql presto round-robin
1个回答
0
投票

您可以使用 NTILE() 函数为项目赋予新的排名,以帮助按页对它们进行排序,唯一的限制是参数必须是常量,但您应该根据要分配的帐户总数来计算它(在你的例子中:10):

WITH accounts(Account, Email, Rank, Country) AS (
    SELECT 'Account_A', 'abc@account_a.com', 1, 'USA' FROM DUAL UNION ALL
    SELECT 'Account_A', 'cde@account_a.com', 2, 'USA' FROM DUAL UNION ALL
    SELECT 'Account_A', 'fgh@account_a.com', 3, 'USA' FROM DUAL UNION ALL
    SELECT 'Account_A', 'klh@account_a.com', 4, 'USA' FROM DUAL UNION ALL
    SELECT 'Account_B', 'abc@account_b.com', 1, 'JAPAN' FROM DUAL UNION ALL
    SELECT 'Account_C', 'xyz@account_c.com', 1, 'INDIA' FROM DUAL UNION ALL
    SELECT 'Account_C', 'pqr@account_c.com', 2, 'INDIA' FROM DUAL UNION ALL
    SELECT 'Account_D', 'efg@account_d.com', 1, 'CHINA' FROM DUAL UNION ALL
    SELECT 'Account_D', 'xyz@account_d.com', 2, 'CHINA' FROM DUAL UNION ALL
    SELECT 'Account_E', 'abc@account_E.com', 1, 'JAPAN' FROM DUAL -- UNION ALL
)   
SELECT * FROM (
    SELECT account, email, RANK, 
        country,
    -- the parameter of the ntile() should be the count(*) of the table
    -- divided by the number of rows of each type you want on the page
        ntile(:ntiles) over(ORDER BY account) AS tile
    FROM accounts
)
order by rank, tile, Account
offset (:page_num-1)*:page_size rows fetch next :page_size rows only
;

第 1 页:

ACCOUNT  |EMAIL            |RANK|COUNTRY|TILE|
---------+-----------------+----+-------+----+
Account_A|abc@account_a.com|   1|USA    |   1|
Account_B|abc@account_b.com|   1|JAPAN  |   5|
Account_C|xyz@account_c.com|   1|INDIA  |   6|
Account_D|efg@account_d.com|   1|CHINA  |   8|
Account_E|abc@account_E.com|   1|JAPAN  |  10|
Account_A|cde@account_a.com|   2|USA    |   2|
Account_C|pqr@account_c.com|   2|INDIA  |   7|
Account_D|xyz@account_d.com|   2|CHINA  |   9|

第 2 页:

ACCOUNT  |EMAIL            |RANK|COUNTRY|TILE|
---------+-----------------+----+-------+----+
Account_A|fgh@account_a.com|   3|USA    |   3|
Account_A|klh@account_a.com|   4|USA    |   4|
© www.soinside.com 2019 - 2024. All rights reserved.