计算/求和子查询中的值并按它排序
Count / sum values in subquery and order by it
我有如下表格:
user
id | status
1 | 0
gallery
id | status | create_by_user_id
1 | 0 | 1
2 | 0 | 1
3 | 0 | 1
media
id | status
1 | 0
2 | 0
3 | 0
gallery_media
fk gallery.id fk media.id
id | gallery_id | media_id | sequence
1 | 1 | 1 | 1
2 | 2 | 2 | 1
3 | 2 | 3 | 2
monitor_traffic
1:gallery 2:media
id | anonymous_id | user_id | endpoint_code | endpoint_id
1 | 1 | | 1 | 2 gallery.id 2
2 | 2 | | 1 | 2 gallery.id 2
3 | | 1 | 2 | 3 media.id 3 include in gallery.id 2
these means gallery.id 2 contain 3 rows
gallery_information
fk gallery.id
id | gallery_id
gallery
包括 media
.
monitor_traffic.endpoint_code
: 1
..画廊; 2
..媒体
如果 1
则 monitor_traffic.endpoint_id
引用 gallery.id
monitor_traffic.user_id
、monitor_traffic.anonymous_id
整数或 null
Objective
我想输出 gallery
行,按 monitor_traffic
中每个 gallery
行的计数排序,然后计算 gallery
中相关的 media
行24=]。最后总结一下。
我提供的查询只计算 monitor_traffic
中的 media
而没有对它们求和,也不计算 monitor_traffic
中的 gallery
。
如何做到这一点?
这是函数的一部分,输入选项然后输出构建查询,类似于 this。我希望找到一个不需要更改查询其他部分的解决方案(可能带有子查询)。
查询:
SELECT
g.*,
row_to_json(gi.*) as gallery_information
FROM gallery g
LEFT JOIN gallery_information gi ON gi.gallery_id = g.id
LEFT JOIN "user" u ON u.id = g.create_by_user_id
-- start
LEFT JOIN gallery_media gm ON gm.gallery_id = g.id
LEFT JOIN (
SELECT
endpoint_id,
COUNT(*) as mt_count
FROM monitor_traffic
WHERE endpoint_code = 2
GROUP BY endpoint_id
) mt ON mt.endpoint_id = m.id
-- end
ORDER BY mt.mt_count desc NULLS LAST;
我建议 CTE 计算 one 聚合中的两种类型,并在 FROM
子句中加入两次:
WITH mt AS ( -- count once for both media and gallery
SELECT endpoint_code, endpoint_id, count(*) AS ct
FROM monitor_traffic
GROUP BY 1, 2
)
SELECT g.*, row_to_json(gi.*) AS gallery_information
FROM gallery g
LEFT JOIN mt ON mt.endpoint_id = g.id -- 1st join to mt
AND mt.endpoint_code = 1 -- gallery
LEFT JOIN (
SELECT gm.gallery_id, sum(ct) AS ct
FROM gallery_media gm
JOIN mt ON mt.endpoint_id = gm.media_id -- 2nd join to mt
AND mt.endpoint_code = 2 -- media
GROUP BY 1
) mmt ON mmt.gallery_id = g.id
LEFT JOIN gallery_information gi ON gi.gallery_id = g.id
ORDER BY mt.ct DESC NULLS LAST -- count of galleries
, mmt.ct DESC NULLS LAST; -- count of "gallery related media"
或者,按两个计数的总和排序:
...
ORDER BY COALESCE(mt.ct, 0) + COALESCE(mmt.ct, 0) DESC;
先聚合,后加入。这可以防止 "proxy-cross joins" 的复杂性,即乘以行:
- Two SQL LEFT JOINS produce incorrect result
LEFT JOIN
到"user"
好像是空运费。删除它:
LEFT JOIN "user" u ON u.id = g.create_by_user_id
不要使用像 "user"
这样的保留字作为标识符,即使只要您使用双引号就可以这样做。非常容易出错。
我有如下表格:
user
id | status
1 | 0
gallery
id | status | create_by_user_id
1 | 0 | 1
2 | 0 | 1
3 | 0 | 1
media
id | status
1 | 0
2 | 0
3 | 0
gallery_media
fk gallery.id fk media.id
id | gallery_id | media_id | sequence
1 | 1 | 1 | 1
2 | 2 | 2 | 1
3 | 2 | 3 | 2
monitor_traffic
1:gallery 2:media
id | anonymous_id | user_id | endpoint_code | endpoint_id
1 | 1 | | 1 | 2 gallery.id 2
2 | 2 | | 1 | 2 gallery.id 2
3 | | 1 | 2 | 3 media.id 3 include in gallery.id 2
these means gallery.id 2 contain 3 rows
gallery_information
fk gallery.id
id | gallery_id
gallery
包括 media
.
monitor_traffic.endpoint_code
: 1
..画廊; 2
..媒体
如果 1
则 monitor_traffic.endpoint_id
引用 gallery.id
monitor_traffic.user_id
、monitor_traffic.anonymous_id
整数或 null
Objective
我想输出 gallery
行,按 monitor_traffic
中每个 gallery
行的计数排序,然后计算 gallery
中相关的 media
行24=]。最后总结一下。
我提供的查询只计算 monitor_traffic
中的 media
而没有对它们求和,也不计算 monitor_traffic
中的 gallery
。
如何做到这一点?
这是函数的一部分,输入选项然后输出构建查询,类似于 this。我希望找到一个不需要更改查询其他部分的解决方案(可能带有子查询)。
查询:
SELECT
g.*,
row_to_json(gi.*) as gallery_information
FROM gallery g
LEFT JOIN gallery_information gi ON gi.gallery_id = g.id
LEFT JOIN "user" u ON u.id = g.create_by_user_id
-- start
LEFT JOIN gallery_media gm ON gm.gallery_id = g.id
LEFT JOIN (
SELECT
endpoint_id,
COUNT(*) as mt_count
FROM monitor_traffic
WHERE endpoint_code = 2
GROUP BY endpoint_id
) mt ON mt.endpoint_id = m.id
-- end
ORDER BY mt.mt_count desc NULLS LAST;
我建议 CTE 计算 one 聚合中的两种类型,并在 FROM
子句中加入两次:
WITH mt AS ( -- count once for both media and gallery
SELECT endpoint_code, endpoint_id, count(*) AS ct
FROM monitor_traffic
GROUP BY 1, 2
)
SELECT g.*, row_to_json(gi.*) AS gallery_information
FROM gallery g
LEFT JOIN mt ON mt.endpoint_id = g.id -- 1st join to mt
AND mt.endpoint_code = 1 -- gallery
LEFT JOIN (
SELECT gm.gallery_id, sum(ct) AS ct
FROM gallery_media gm
JOIN mt ON mt.endpoint_id = gm.media_id -- 2nd join to mt
AND mt.endpoint_code = 2 -- media
GROUP BY 1
) mmt ON mmt.gallery_id = g.id
LEFT JOIN gallery_information gi ON gi.gallery_id = g.id
ORDER BY mt.ct DESC NULLS LAST -- count of galleries
, mmt.ct DESC NULLS LAST; -- count of "gallery related media"
或者,按两个计数的总和排序:
...
ORDER BY COALESCE(mt.ct, 0) + COALESCE(mmt.ct, 0) DESC;
先聚合,后加入。这可以防止 "proxy-cross joins" 的复杂性,即乘以行:
- Two SQL LEFT JOINS produce incorrect result
LEFT JOIN
到"user"
好像是空运费。删除它:
LEFT JOIN "user" u ON u.id = g.create_by_user_id
不要使用像 "user"
这样的保留字作为标识符,即使只要您使用双引号就可以这样做。非常容易出错。