PostgreSQL随机行分配

时间:2019-07-15 13:47:47

标签: postgresql

我有2张桌子

Student

|---------------------|------------------|
|         id          |     studentname  |
|---------------------|------------------|
|          1          |     studentA     |
|---------------------|------------------|
|          2          |     studentB     |
|---------------------|------------------|
|          3          |     studentC     |
|---------------------|------------------|
|          4          |     studentD     |
|---------------------|------------------|  

Chair

|---------------------|------------------|
|      id             |     chairname    |
|---------------------|------------------|
|          1          |     chairA       |
|---------------------|------------------|
|          2          |     chairB       |
|---------------------|------------------|
|          3          |     chairC       |
|---------------------|------------------|

我需要一个查询来将学生随机分配到Postgresql中的椅子上。注意,可能有比学生更多的椅子,反之亦然。如果学生人数超过主席人数,则未分配的学生的主席人数将为空。

对于以上表格,我们应该得到类似

的结果
|---------------------|------------------|
|      studentname    |     chairname    |
|---------------------|------------------|
|          studentA   |     chairC       |
|---------------------|------------------|
|          studentB   |     chairA       |
|---------------------|------------------|
|          studentC   |     chairB       |
|---------------------|------------------|
|          studentD   |     NULL         |
|---------------------|------------------|

OR

|---------------------|------------------|
|      studentname    |     chairname    |
|---------------------|------------------|
|          studentA   |     chairA       |
|---------------------|------------------|
|          studentB   |     chairC       |
|---------------------|------------------|
|          studentC   |     NULL         |
|---------------------|------------------|
|          studentD   |     chairB       |
|---------------------|------------------|

有什么想法可以在postgresql中完成吗?

1 个答案:

答案 0 :(得分:2)

您可以尝试随机使用ROW_NUMBER将学生ID分配给各个椅子:

WITH cte1 AS (
    SELECT chairname, ROW_NUMBER() OVER (ORDER BY RANDOM()) rn
    FROM Chair
),
cte2 AS (
    SELECT studentname, ROW_NUMBER() OVER (ORDER BY id) rn
    FROM Student
)

SELECT
    s.studentname,
    c.chairname
FROM cte2 s
LEFT JOIN cte1 c
    ON s.rn = c.rn;

enter image description here

Demo

请注意,我实际上在两个表(包括Student表)中都生成了行号序列。这是为了确保我们始终比较两个表之间匹配的行号值。

编辑:将LEFT JOIN替换为FULL OUTER JOIN,以处理学生人数超出主席人数的情况,反之亦然。