带有 INNER JOIN 的 Postgres COUNT 列值数
Postgres COUNT number of column values with INNER JOIN
我正在 Postgres 9.3 中创建报告。这是我的 SQL Fiddle.
基本上我有两个表,responses
和questions
,结构是:
responses
->id
->question_id
->response
questions
->id
->question
->costperlead
对于列 response
,只能有 3 个值,Yes/No/Possbily
,
我的报告应该包含以下列:
question_id
, # of Yes Responses
, # of No Responses
, # of Possbily Responses
, Revenue
然后:
# of Yes Responses - count of all Yes values in the response column
# of No Responses - count of all No values in the response column
# of Possbily Responses - count of all 'Possbily' values in the response column
收入是 costperlead
*(是的回复数 + 可能的回复数)。
我不知道如何构造查询,我是新手,而且我来自 MySQL,所以有些事情对于 postgres 是不同的。在我的 SQL Fiddle 示例中,大多数响应是 Yes 和 Null,最终没问题,可能会有和 No.
到目前为止我只有:
SELECT a.question_id
FROM responses a
INNER JOIN questions b ON a.question_id = b.id
WHERE a.created_at = '2015-07-17'
GROUP BY a.question_id;
你应该试试:
SELECT a.question_id,
SUM(CASE WHEN a.response = 'Yes' THEN 1 ELSE 0 END) AS NumsOfYes,
SUM(CASE WHEN a.response = 'No' THEN 1 ELSE 0 END) AS NumsOfNo,
SUM(CASE WHEN a.response = 'Possibly' THEN 1 ELSE 0 END) AS NumOfPossibly,
costperlead * SUM(CASE WHEN a.response = 'Yes' THEN 1 ELSE 0 END) + SUM(CASE WHEN a.response = 'Possibly' THEN 1 ELSE 0 END) AS revenue
FROM responses a
INNER JOIN questions b ON a.question_id = b.id
GROUP BY a.question_id, b.costperlead
由于唯一的谓词过滤来自 table responses
的行,最有效的做法是先聚合响应,然后加入问题:
SELECT *, q.costperlead * (r.ct_yes + r.ct_maybe) AS revenue
FROM (
SELECT question_id
, count(*) FILTER (WHERE response = 'Yes') AS ct_yes
, count(*) FILTER (WHERE response = 'No') AS ct_no
, count(*) FILTER (WHERE response = 'Possibly') AS ct_maybe
FROM responses
WHERE created_at = '2015-07-17'
GROUP BY 1
) r
JOIN questions q ON q.id = r.question_id;
db<>fiddle here
这使用聚合 FILTER
子句(在 Postgres 9.4 或更高版本中)。参见:
- Aggregate columns with additional (distinct) filters
旁白:考虑将 response
实现为 boolean
类型 true
/false
/null
.
对于 Postgres 9.3:
SELECT *, q.costperlead * (r.ct_yes + r.ct_maybe) AS revenue
FROM (
SELECT question_id
, count(response = 'Yes' OR NULL) AS ct_yes
, count(response = 'No' OR NULL) AS ct_no
, count(response = 'Possibly' OR NULL) AS ct_maybe
FROM responses
WHERE created_at = '2015-07-17'
GROUP BY 1
) r
JOIN questions q ON q.id = r.question_id;
技术综合比较:
我正在 Postgres 9.3 中创建报告。这是我的 SQL Fiddle.
基本上我有两个表,responses
和questions
,结构是:
responses
->id
->question_id
->response
questions
->id
->question
->costperlead
对于列 response
,只能有 3 个值,Yes/No/Possbily
,
我的报告应该包含以下列:
question_id
, # of Yes Responses
, # of No Responses
, # of Possbily Responses
, Revenue
然后:
# of Yes Responses - count of all Yes values in the response column
# of No Responses - count of all No values in the response column
# of Possbily Responses - count of all 'Possbily' values in the response column
收入是 costperlead
*(是的回复数 + 可能的回复数)。
我不知道如何构造查询,我是新手,而且我来自 MySQL,所以有些事情对于 postgres 是不同的。在我的 SQL Fiddle 示例中,大多数响应是 Yes 和 Null,最终没问题,可能会有和 No.
到目前为止我只有:
SELECT a.question_id
FROM responses a
INNER JOIN questions b ON a.question_id = b.id
WHERE a.created_at = '2015-07-17'
GROUP BY a.question_id;
你应该试试:
SELECT a.question_id,
SUM(CASE WHEN a.response = 'Yes' THEN 1 ELSE 0 END) AS NumsOfYes,
SUM(CASE WHEN a.response = 'No' THEN 1 ELSE 0 END) AS NumsOfNo,
SUM(CASE WHEN a.response = 'Possibly' THEN 1 ELSE 0 END) AS NumOfPossibly,
costperlead * SUM(CASE WHEN a.response = 'Yes' THEN 1 ELSE 0 END) + SUM(CASE WHEN a.response = 'Possibly' THEN 1 ELSE 0 END) AS revenue
FROM responses a
INNER JOIN questions b ON a.question_id = b.id
GROUP BY a.question_id, b.costperlead
由于唯一的谓词过滤来自 table responses
的行,最有效的做法是先聚合响应,然后加入问题:
SELECT *, q.costperlead * (r.ct_yes + r.ct_maybe) AS revenue
FROM (
SELECT question_id
, count(*) FILTER (WHERE response = 'Yes') AS ct_yes
, count(*) FILTER (WHERE response = 'No') AS ct_no
, count(*) FILTER (WHERE response = 'Possibly') AS ct_maybe
FROM responses
WHERE created_at = '2015-07-17'
GROUP BY 1
) r
JOIN questions q ON q.id = r.question_id;
db<>fiddle here
这使用聚合 FILTER
子句(在 Postgres 9.4 或更高版本中)。参见:
- Aggregate columns with additional (distinct) filters
旁白:考虑将 response
实现为 boolean
类型 true
/false
/null
.
对于 Postgres 9.3:
SELECT *, q.costperlead * (r.ct_yes + r.ct_maybe) AS revenue
FROM (
SELECT question_id
, count(response = 'Yes' OR NULL) AS ct_yes
, count(response = 'No' OR NULL) AS ct_no
, count(response = 'Possibly' OR NULL) AS ct_maybe
FROM responses
WHERE created_at = '2015-07-17'
GROUP BY 1
) r
JOIN questions q ON q.id = r.question_id;
技术综合比较: