sql - PostgreSQL提取小时和0总和值分组不显示结果
问题描述
我在 Postgres 中有这个 SQL 请求
SELECT CAST(extract(hour from
CAST("public"."v_mdmeddialogues"."datecreation" AS timestamp)) AS integer) AS "datecreation",
"public"."v_mdmeddialogues"."refspecialty" AS "refspecialty",
"Refspecialty"."label" AS "label",
COALESCE(count(distinct "public"."v_mdmeddialogues"."iddialogue"), 0) AS "count",
COALESCE(sum("public"."v_mdmeddialogues"."timespent"), 0) AS "heures"
FROM "public"."v_mdmeddialogues"
LEFT JOIN "public"."v_mdiddoctors" "Refuser" ON "public"."v_mdmeddialogues"."refuser" = "Refuser"."iduser"
LEFT JOIN "public"."v_mdparamspecialties" "Refspecialty"
ON "public"."v_mdmeddialogues"."refspecialty" = "Refspecialty"."idspecialty"
WHERE (date_trunc('month', CAST("public"."v_mdmeddialogues"."datecreation" AS timestamp)) BETWEEN date_trunc('month',
CAST(
(CAST(now() AS timestamp) + (INTERVAL '-3 month')) AS timestamp)) AND date_trunc('month', CAST(now() AS timestamp)) AND
"Refspecialty"."label" = 'Dermatologie' AND
"public"."v_mdmeddialogues"."codedialogueaction" in ('RESPONSE', 'TRANSFER'))
AND extract('dow' FROM "public"."v_mdmeddialogues"."datecreation") IN (0, 6)
GROUP BY CAST(extract(hour from CAST("public"."v_mdmeddialogues"."datecreation" AS timestamp)) AS integer),
"public"."v_mdmeddialogues"."refspecialty", "Refspecialty"."label"
ORDER BY CAST(extract(hour from CAST("public"."v_mdmeddialogues"."datecreation" AS timestamp)) AS integer) ASC,
"public"."v_mdmeddialogues"."refspecialty" ASC, "Refspecialty"."label" ASC;
问题是在凌晨 4 点到 5 点之间“发生”没有任何价值,因此结果显示:
我的桌子是:
create table mdmeddialogues
(
iddialogue varchar(255),
codedialoguetype varchar(255),
refdialogueroot bigint,
codedialogueaction varchar(255),
refuser varchar(255),
refspecialty varchar(255),
datecreation timestamp,
refoperator varchar(255),
source varchar(255),
timespent bigint,
datelastupdate timestamp
);
create table mdparamspecialties
(
idspecialty varchar(255),
code varchar(255),
label varchar(255),
active bit,
exclusive bit,
valid bit,
datelastupdate timestamp
);
如您所见,结果跳过了 4 中的值datecreation
。如何在 和 中显示具有空值 (0) 的这一count
行heures
?
谢谢您的帮助
解决方案
首先,这与您的问题是分开的,但是v_mdmeddialogues
在查询的可读性方面添加别名并进行一些格式化确实有很大帮助。此外,您还有很多不必要的转换,例如将时间戳转换为时间戳。我假设datecreation
是一个文本字段,在这种情况下,我将演员留在原地,但如果这是一个日期/时间,那么该演员也是不必要的,甚至有点误导。最后,在我看来,多余的报价会分散注意力。唯一需要引号的时候是在表的 DDL 中出现引号时,我强烈反对在几乎所有情况下都这样做。
无论如何,使用上述观察对原始查询进行快速重构可能如下所示(为简单起见,我将 public.v_mdmeddialogues 别名为“md”):
SELECT
extract (hour from md.datecreation) AS datecreation,
md.refspecialty AS refspecialty,
Refspecialty.label AS label,
COALESCE(count(distinct md.iddialogue), 0) AS count,
COALESCE(sum(md.timespent), 0) AS heures
FROM
mdmeddialogues md
LEFT JOIN mdiddoctors Refuser ON
md.refuser = Refuser.iduser
LEFT JOIN mdparamspecialties Refspecialty
ON md.refspecialty = Refspecialty.idspecialty
WHERE
date_trunc('month', md.datecreation) BETWEEN
date_trunc('month', current_timestamp) - INTERVAL '3 month' AND
date_trunc('month', current_timestamp) AND
Refspecialty.label = 'Dermatologie' AND
md.codedialogueaction in ('RESPONSE', 'TRANSFER') and
extract('dow' FROM md.datecreation) IN (0, 6)
GROUP BY
datecreation, md.refspecialty, Refspecialty.label
ORDER BY
datecreation ASC, md.refspecialty ASC, Refspecialty.label ASC;
免责声明:我可能把一两件事搞砸了,但希望你能看到这更具可读性和更容易理解。
现在谈谈你的问题。如果您有一个已知的数据集作为输出,您可以生成该数据集,然后左外连接我们的查询。在这种情况下,您似乎想要一个有保证的 0-23。为此,您可以使用 agenerate_series (0, 23)
创建这些,然后将其保留下来:
SELECT
gs.datecreation,
md.refspecialty AS refspecialty,
Refspecialty.label AS label,
COALESCE(count(distinct md.iddialogue), 0) AS count,
COALESCE(sum(md.timespent), 0) AS heures
FROM
generate_series (0, 23) gs (datecreation)
left join mdmeddialogues md on
gs.datecreation = extract (hour from md.datecreation) and
date_trunc('month', md.datecreation) BETWEEN
date_trunc('month', current_timestamp) - INTERVAL '3 month' AND
date_trunc('month', current_timestamp) AND
md.codedialogueaction in ('RESPONSE', 'TRANSFER') and
extract('dow' FROM md.datecreation) IN (0, 6)
LEFT JOIN mdiddoctors Refuser ON
md.refuser = Refuser.iduser
LEFT JOIN mdparamspecialties Refspecialty on
md.refspecialty = Refspecialty.idspecialty and
Refspecialty.label = 'Dermatologie'
GROUP BY
gs.datecreation, md.refspecialty, Refspecialty.label
ORDER BY
gs.datecreation ASC, md.refspecialty ASC, Refspecialty.label ASC;
如果您希望refspecialty
andlabel
值也显示出来,那是另一回事。由于这两个值之一在 where 子句中是硬编码的,因此您可以将其添加到合并中。
推荐阅读
- python - 同一图像的分类给出不同的结果
- safari - Safari - createMediaElementSource 不起作用?
- php - 连接到 mongodb 时的权限问题
- javascript - 在 Firebase 云函数中使用导入
- javascript - 如何从自己的 URL 中找到网站 IP?
- python - 添加可见 gpu 设备时遇到问题:0
- javascript - 通过 Ajax 将数据从 Laravel 7 视图传递到控制器
- hdfs - 带有 HDFS 工件存储的 MLFLOW
- javascript - 如何修复无法在角度材料数据表中设置未定义的属性“排序”?
- c# - 创建一个将返回 JSON 数据而不更改当前 ASP.NET MVC 登录机制的新登录名