[英]SQL select and order by (count of related records inside a second table) subtracted by (count of related records inside second table with condition)
I am trying to SELECT every record in a table one ORDER ed BY the COUNT of records inside a second table that store the related primary key value and WHERE 'positive' is true, subtracted by the COUNT of records inside the second table that store the related primary key value and WHERE 'positive' is false.我正在尝试SELECT表中的每条记录一个ORDER BY存储相关主键值的第二个表内的记录数,并且WHERE ' positive ' 为真,减去第二个表内存储的记录数相关的主键值和WHERE 'positive' 为 false。
Here is my database structure这是我的数据库结构
Table 1表格1
id ID | data数据 |
---|---|
0 0 | zero零 |
1 1个 | one一 |
2 2个 | two二 |
3 3个 | three三 |
Table 2表 2
id ID | related_tableone_id related_tableone_id | positive积极的 |
---|---|---|
0 0 | 1 1个 | 0 0 |
1 1个 | 2 2个 | 1 1个 |
2 2个 | 2 2个 | 0 0 |
3 3个 | 2 2个 | 1 1个 |
4 4个 | 3 3个 | 1 1个 |
5 5个 | 3 3个 | 1 1个 |
Here is what I am trying to get这是我想要得到的
id ID | data数据 | subtracted_counts (i dont need this but these values are what the records should be ordered by) subtracted_counts(我不需要这个,但这些值是记录的排序依据) |
---|---|---|
3 3个 | three三 | 2 2个 |
2 2个 | two二 | 1 1个 |
0 0 | zero零 | 0 0 |
1 1个 | one一 | -1 -1 |
For better understanding on what i want to achieve:为了更好地理解我想要实现的目标:
This database structure can be compared with a voting system , where Table 1 are entities that can be voted up or voted down .可以将此数据库结构与投票系统进行比较,其中表 1 是可以投票赞成或投票反对的实体。
In this case, Table 2 would store the votes with positive=true for an upvote and positive=false for a downvote .在这种情况下,表 2 将存储positive=true表示赞成票和positive=false表示反对票的选票。
The goal is to get all entities ORDER ed BY their summarized vote value .目标是让所有实体按其汇总的投票值排序。
(Within a single query) (在单个查询中)
My research我的研究
I found this post SQL - How To Order Using Count From Another Table , tho there is no subtraction logic我发现这篇文章SQL - How To Order Using Count From Another Table ,虽然没有减法逻辑
I tried this query我试过这个查询
SELECT
tableone.*,
COUNT(related_tableone_id) - COUNT(negative_related_tableone_id) AS subtracted_count
FROM
tableone
LEFT JOIN
(SELECT related_tableone_id
FROM tabletwo
WHERE positive = true) AS positives ON tableone.id = positives.related_tableone_id
LEFT JOIN
(SELECT related_tableone_id AS negative_related_tableone_id
FROM tabletwo
WHERE positive = false) AS negatives ON tableone.id = negatives.negative_related_tableone_id
GROUP BY
tableone.id
ORDER BY
subtracted_count DESC;
But it doesn't subtract the counts right for some reason and there is probably a more clear solution但是由于某种原因它并没有正确地减去计数,并且可能有一个更清晰的解决方案
A single subquery can count both upvotes and downvotes, using conditional aggregation.使用条件聚合,单个子查询可以计算赞成票和反对票。 I would use a lateral join to do the computation:我会使用横向连接来进行计算:
select t1.*, t2.*
from tableone t1
cross join lateral (
select
sum(case when t2.positive = true then 1 else 0 end) upvotes,
sum(case when t2.positive = false then 1 else 0 end) downvotes
from tabletwo t2
where t2.related_tableone_id = t1.id
) t2
order by t2.upvotes - t2.downvotes desc, t1.id
Depending on your database, the lateral join might be introduced by cross apply
instead (eg in Oracle or SQL Server).根据您的数据库,横向连接可能由cross apply
引入(例如在 Oracle 或 SQL 服务器中)。
Use a LEFT
join of Table1
to Table2
and conditional aggregation in the ORDER BY
clause:在ORDER BY
子句中使用Table1
到Table2
的LEFT
连接和条件聚合:
SELECT t1.id, t1.data
FROM Table1 t1 LEFT JOIN Table2 t2
ON t2.related_tableone_id = t1.id
GROUP BY t1.id
ORDER BY SUM(CASE t2.positive WHEN true THEN 1 WHEN false THEN -1 ELSE 0 END) DESC;
or, a correlated subquery in the ORDER BY
clause (which may perform better):或者, ORDER BY
子句中的相关子查询(可能表现更好):
SELECT t1.*
FROM Table1 t1
ORDER BY (
SELECT COALESCE(SUM(CASE t2.positive WHEN true THEN 1 WHEN false THEN -1 END) , 0)
FROM Table2 t2
WHERE t2.related_tableone_id = t1.id
) DESC;
See the demo (works in MySql, Postgresql and SQLite).请参阅演示(适用于 MySql、Postgresql 和 SQLite)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.