【发布时间】:2019-09-12 07:49:47
【问题描述】:
我正在尝试在 1 个 SQL 查询中从 Stores、Offers、Products 和 Jobs 表中获取我需要的所有详细信息。
数据库关系:
- 提供belongs_to Store
- 提供 has_many 产品
- 提供 has_many 工作
问题是:我想要针对不同的工作状态进行工作计数。
下面的查询确实有效,但我不喜欢它有多大,并且这部分有多个重复项:WHERE "jobs"."offer_id" = "offers"."id"。有没有办法使这个查询优化并且可能更小?
SELECT
"offers".*,
"stores"."name" AS store_name,
(
SELECT COUNT(*)
FROM "products"
WHERE "products"."offer_id" = "offers"."id"
) AS products_count,
(
SELECT COUNT(*)
FROM "jobs"
WHERE "jobs"."offer_id" = "offers"."id"
) AS jobs_count,
(
SELECT COUNT(*)
FROM "jobs"
WHERE "jobs"."offer_id" = "offers"."id" AND "jobs"."status" = 1
) AS jobs_in_progress_count,
(
SELECT COUNT(*)
FROM "jobs"
WHERE "jobs"."offer_id" = "offers"."id" AND "jobs"."status" = 2
) AS jobs_done_count,
(
SELECT COUNT(*)
FROM "jobs"
WHERE "jobs"."offer_id" = "offers"."id" AND "jobs"."status" = 3
) AS jobs_error_count
FROM "offers"
LEFT JOIN "stores" ON "stores"."id" = "offers"."store_id"
GROUP BY "offers"."id", "stores"."name"
ORDER BY "offers"."created_at" DESC
SELECT
"offers".*,
"stores"."name" AS store_name,
products.products_count,
jobs.jobs_count,
jobs.jobs_in_progress_count,
jobs.jobs_done_count,
jobs.jobs_error_count
FROM "offers"
LEFT JOIN "stores" ON "stores"."id" = "offers"."store_id"
LEFT JOIN (
SELECT p.offer_id,
COUNT(*) AS products_count
FROM "products" p
GROUP BY p.offer_id
) "products" ON "products"."offer_id" = "offers"."id"
LEFT JOIN (
SELECT j.offer_id,
COUNT(*) AS jobs_count,
COUNT(*) FILTER (WHERE j.status = 1) AS jobs_in_progress_count,
COUNT(*) FILTER (WHERE j.status = 2) AS jobs_done_count,
COUNT(*) FILTER (WHERE j.status = 3) AS jobs_error_count
FROM "jobs" j
GROUP BY j.offer_id
) "jobs" ON "jobs"."offer_id" = "offers"."id"
GROUP BY "offers"."id", "stores"."name", "products"."products_count", "jobs"."jobs_count", "jobs"."jobs_in_progress_count", "jobs"."jobs_done_count", "jobs"."jobs_error_count"
ORDER BY "offers"."created_at" DESC
【问题讨论】:
-
我认为您可以对每个表(产品、工作等)进行左连接并执行
SELECT COUNT(products.id) as products_count、SELECT COUNT(jobs.id) as jobs_count等操作 -
如果我离开联接(产品、工作)查询时间由于某种原因从 5 毫秒变为 50 毫秒。我正在使用 PostgreSQL
标签: sql postgresql