如何在自联接中获取唯一值以及如何在 psql 中动态获取 LIMIT 数
Posted
技术标签:
【中文标题】如何在自联接中获取唯一值以及如何在 psql 中动态获取 LIMIT 数【英文标题】:How to get unique values in the self join and how to get LIMIT number dynamically in psql 【发布时间】:2016-02-13 20:23:05 【问题描述】:您好,我只是在学习数据库并在下表中练习我的技能
id | name | wins | matches
-----+-------------------+------+---------
205 | Twilight Sparkle | 0 | 0
206 | Fluttershy | 0 | 0
207 | Applejack | 0 | 0
208 | Pinkie Pie | 0 | 0
209 | Rarity | 0 | 0
210 | Rainbow Dash | 0 | 0
211 | Princess Celestia | 0 | 0
212 | Princess Luna | 0 | 0
我的工作在这里 返回下一轮比赛的球员对列表。 假设注册的玩家数量为偶数,每个玩家 在配对中只出现一次。每个玩家都与另一个配对 获胜记录相等或几乎相等的玩家,即在积分榜上与他或她相邻的玩家。
返回: 元组列表,每个元组包含 (id1, name1, id2, name2) id1:第一个玩家的唯一id name1:第一个玩家的名字 id2:第二个玩家的唯一id name2:第二个玩家的名字
为了实现这些目标,我已经完成了自我加入该表并编写了类似这样的代码
SELECT a.id, a.name, b.id, b.name
FROM results AS a, results AS b
WHERE a.id > b.id and a.wins = b.wins
LIMIT COUNT(a.id)/2;
好像不行。请帮我解决这个问题。
谢谢。
【问题讨论】:
您使用的是 mysql 还是 PostgreSQL? - 它们是两个不同的关系型数据库 我正在使用 PostgreSQL。 【参考方案1】:您可以根据他们的胜利对他们进行排序,然后加入该序列,因此他们可能获得相同的胜利或下一个最接近的胜利:
WITH seq_results AS
(
SELECT
id,
name,
ROW_NUMBER() OVER(ORDER BY wins DESC) AS seq
FROM
results
)
SELECT
r1.id,
r1.name,
r2.id,
r2.name
FROM
seq_results r1
JOIN
seq_results r2
ON (r1.seq = (r2.seq - 1))
AND (r2.seq % 2 = 0);
根据您的要求,以下是有关其工作原理的一些信息。我强烈建议您访问 PostgreSQL 的文档 - 它确实是一些最好的文档:http://www.postgresql.org/docs/current/static/
第一部分是公用表表达式 (CTE)。它允许我在内存中创建一个表以供后续查询使用。您可以轻松地创建一个临时表,但不必删除这些等。 见:http://www.postgresql.org/docs/current/static/queries-with.html
WITH seq_results AS
(
SELECT
id,
name,
ROW_NUMBER() OVER(ORDER BY wins DESC) AS seq
FROM
results
)
在这个 CTE 中,我使用窗口函数对每条记录进行排序/顺序编号。稍后我将在加入时使用这些数字。见:http://www.postgresql.org/docs/current/static/functions-window.html
SELECT
r1.id,
r1.name,
r2.id,
r2.name
FROM
seq_results r1
JOIN
seq_results r2
ON (r1.seq = (r2.seq - 1))
AND (r2.seq % 2 = 0);
在上面,我使用序列将 CTE 加入到自身中。我将 CTE r2
的第二个实例的序列“偏移”了 -1,本质上是将两个连续记录连接在一起。
如果我只在连接中指定该条件,我会返回超过预期的 4 条记录。我需要确保“左侧”上的 id 和名称不在“右侧”上,因此我决定仅包括左侧的奇数序列记录和右侧的偶数记录。为此,我使用了模运算符%
来确保r2
只返回序列为偶数的记录。
最后,因为连接是内连接(JOIN
与 INNER JOIN
相同),所以不会返回 r1
中的任何偶数序列。
【讨论】:
我不知道你为什么要在查询前加上create table
,但逻辑是正确的。
这有什么不明白的?表seq_results
在最终查询中被使用了两次,所以它不能是CTE。
嗨,我收到此错误ValueError: For eight players, swissPairings should return 4 pairs. Got 3
我认为列表中缺少一些我尝试左连接但我得到 8 对。我认为超过 2 人的分数相同。
嗨,我收到此错误ValueError: For eight players, swissPairings should return 4 pairs. Got 3
我认为列表中缺少一些我尝试过左连接但我得到 8 对。我认为超过 2 人的分数相同。
这个错误来自哪里? ValueError: For eight players, swissPairings should return 4 pairs. Got 3
以上是关于如何在自联接中获取唯一值以及如何在 psql 中动态获取 LIMIT 数的主要内容,如果未能解决你的问题,请参考以下文章
了解在 SQL 查询的自联接中使用“Between”条件时的逻辑查询处理