SQL中的匹配算法
我的数据库中有下表SQL中的匹配算法,sql,postgresql,relational-division,Sql,Postgresql,Relational Division,我的数据库中有下表 # select * FROM matches; name | prop | rank ------+------+------- carl | 1 | 4 carl | 2 | 3 carl | 3 | 9 alex | 1 | 8 alex | 2 | 5 alex | 3 | 6 alex | 3 | 8 alex | 2 | 11 ann
# select * FROM matches;
name | prop | rank
------+------+-------
carl | 1 | 4
carl | 2 | 3
carl | 3 | 9
alex | 1 | 8
alex | 2 | 5
alex | 3 | 6
alex | 3 | 8
alex | 2 | 11
anna | 3 | 8
anna | 3 | 13
anna | 2 | 14
(11 rows)
每个人在工作中都按照不同的属性/标准(称为“道具”)进行排名,而表现则被称为“排名”。如示例所示,该表包含(name,prop)的多个值。我想从一些要求中得到最好的候选人。例如,我需要一名具有(prop=1且排名>5)
和(prop=3且排名>=8)
的候选人。然后,我们必须能够根据候选人的排名对其进行排序,以获得最佳候选人
编辑:每个人必须满足所有要求
如何在SQL中实现这一点 如果我理解您的问题,那么您只需要执行以下操作:
SELECT * FROM matches where (prop = 1 AND rank > 5) OR (prop = 3 AND rank >= 8) ORDER BY rank
它为您提供按排名排序的prop=1且排名>5或prop=3且排名>=8的日期。如果我理解您的问题,那么您只需要执行以下操作:
SELECT * FROM matches where (prop = 1 AND rank > 5) OR (prop = 3 AND rank >= 8) ORDER BY rank
select x.name, max(x.rank)
from matches x
join (
select name from matches where prop = 1 AND rank > 5
intersect
select name from matches where prop = 3 AND rank >= 8
) y
on x.name = y.name
group by x.name
order by max(rank);
它为您提供了按排名排序的prop=1且排名>5或prop=3且排名>=8的CANIDATE。过滤数据以匹配您的标准非常简单(如Amir和sternze所示):
select x.name, max(x.rank)
from matches x
join (
select name from matches where prop = 1 AND rank > 5
intersect
select name from matches where prop = 3 AND rank >= 8
) y
on x.name = y.name
group by x.name
order by max(rank);
问题是如何聚合这些数据,以便每个候选对象只有一行
我建议你这样做:
SELECT m.name,
MAX(DeltaRank1) AS MaxDeltaRank1,
MAX(DeltaRank3) AS MaxDeltaRank3
FROM (
SELECT name,
(CASE WHEN prop=1 THEN rank-6 ELSE 0 END) AS DeltaRank1,
(CASE WHEN prop=3 THEN rank-8 ELSE 0 END) AS DeltaRank3,
FROM matches
) m
GROUP BY m.name
HAVING MaxDeltaRank1>0 AND MaxDeltaRank3>0
SORT BY MaxDeltaRank1+MaxDeltaRank3 DESC;
这将根据候选人在prop1和prop3中超过目标排名的程度之和对候选人进行排序。不过,您可以使用不同的逻辑来指示哪一个是最好的
在上述情况下,结果应为:
name | MaxDeltaRank1 | MaxDeltaRank3
------+---------------+--------------
alex | 3 | 0
。。。因为anna和carl都没有达到要求的级别。过滤数据以符合您的标准非常简单(如Amir和sternze所示): 问题是如何聚合这些数据,以便每个候选对象只有一行 我建议你这样做:
SELECT m.name,
MAX(DeltaRank1) AS MaxDeltaRank1,
MAX(DeltaRank3) AS MaxDeltaRank3
FROM (
SELECT name,
(CASE WHEN prop=1 THEN rank-6 ELSE 0 END) AS DeltaRank1,
(CASE WHEN prop=3 THEN rank-8 ELSE 0 END) AS DeltaRank3,
FROM matches
) m
GROUP BY m.name
HAVING MaxDeltaRank1>0 AND MaxDeltaRank3>0
SORT BY MaxDeltaRank1+MaxDeltaRank3 DESC;
这将根据候选人在prop1和prop3中超过目标排名的程度之和对候选人进行排序。不过,您可以使用不同的逻辑来指示哪一个是最好的
在上述情况下,结果应为:
name | MaxDeltaRank1 | MaxDeltaRank3
------+---------------+--------------
alex | 3 | 0
。。。因为安娜和卡尔都没有达到要求的级别。关系分裂的典型案例。我们在这个相关问题下汇集了一整套技术:
假设你想要一个人的最低等级,我可以用以下方法解决你的特殊情况: 还假设每个人的姓名都是唯一的。实际上,您可能会对
person
表的pk列使用某种外键。如果您有这样一个
person
表,那么最好的排名将存储在那里的一列中…关系划分的典型案例。我们在这个相关问题下汇集了一整套技术:假设你想要一个人的最低等级,我可以用以下方法解决你的特殊情况: 还假设每个人的姓名都是唯一的。实际上,您可能会对
person
表的pk列使用某种外键。如果你有这样一个
person
表,最好的排名会存储在那里的一列中…你能给问题添加一个期望的结果吗?这真的很简单。搜索“通过SQL示例选择订单在哪里”,您应该考虑数据规范化。如果我理解正确,您需要这两个条件的标准自联接,然后是order by语句。如果候选人对所选的道具有多个等级,您希望得到什么?更具体地说,如果他们中的一些人通过了你的条件,而另一些人没有通过。@EnnoShioji:这是一个误解。关系划分一点也不简单。你能给这个问题增加一个期望的结果吗?这真的很简单。搜索“通过SQL示例选择订单在哪里”,您应该考虑数据规范化。如果我理解正确,您需要这两个条件的标准自联接,然后是order by语句。如果候选人对所选的道具有多个等级,您希望得到什么?更具体地说,如果他们中的一些人通过了你的条件,而另一些人没有通过。@EnnoShioji:这是一个误解。关系划分一点也不简单。max(x.rank)
失败,因为大多数秩值都来自y
——您忘了包含rank
。@Erwin,我不确定我是否理解您的注释,y是一个派生表,由完全满足这两个条件的名称组成。秩不能是y的一部分,因为这意味着秩在两种情况下必须相同。另一方面,x包含这些用户的所有列组。你能举一个查询失败的例子吗?啊,我明白了。我的思绪。您将返回到匹配项
,并检索每个符合条件的名称的所有行。所以我的评论是错误的。之前的查询中有一个输入错误,我在y中没有表,因此可能会把事情搞砸,对此我很抱歉。max(x.rank)
失败,因为大多数秩值都来自y
——您忘记了包含rank
。@Erwin,我不确定我是否理解您的评论,Y是一个派生表,由完全满足这两个条件的名称组成。秩不能是y的一部分,因为这意味着秩在两种情况下必须相同。另一方面,x包含这些用户的所有列组。你能举一个查询失败的例子吗?啊,我明白了。我的思绪。您将返回到匹配项
,并检索每个符合条件的名称的所有行。所以我的评论是错误的。之前的查询中有一个输入错误,我在y中没有表,所以可能会把事情搞砸,对此表示抱歉。