我尝试使用WITH
子句获取数据透视表,但我仍然坚持如何返回多个或重复行使用MAX()
。
这是我的原始查询:
SELECT b.detail_id, a.sampling_date, a.sampling_area,
b.sampling_point, b.sampling_type,
b.ha_tpc, b.ha_entero, b.ha_ecoli, b.ha_salmonella
FROM tbl_header a
JOIN tbl_detail b ON a.headerid = b.headerid
WHERE
a.sampling_date = '2016-12-09' AND
a.sampling_area = 'CMP' AND
(b.sampling_point ~* '.*(flex).*' OR b.sampling_point ~* '.*(HPM).*' OR b.sampling_point ~* '.*(fr).*') AND
(b.sampling_type = 'Personil' OR b.sampling_type = 'Equipment')
以下是结果:
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
detail_id | sampling_date | sampling_area | sampling_point | sampling_type | ha_tpc | ha_entero | ha_ecoli | ha_salmonella |
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
24243 | 2016-12-09 | CMP | BOIL013 (OPERATOR ENFLEX) | Personil | 500 | 50 | Abs | Abs |
24289 | 2016-12-09 | CMP | MP115 (OPR ENFLEX) | Personil | 300 | 50 | Abs | Abs |
24284 | 2016-12-09 | CMP | WT033 (FR) | Personil | 250 | 50 | Abs | Abs |
使用这些记录,我尝试创建如下所示的数据透视查询:
WITH tmp_date AS (
SELECT sampling_date.sampling_date::date AS sampling_date
FROM generate_series(
((
SELECT min(tbl_header.sampling_date) AS min
FROM tbl_header
))::timestamp with time zone,
((
SELECT max(tbl_header.sampling_date) AS max
FROM tbl_header
))::timestamp with time zone, '1 day'::interval
) sampling_date(sampling_date)
),
tmp_detail AS (
SELECT a.sampling_date, a.sampling_area,
b.detail_id, b.sampling_point, b.sampling_type,
b.ha_tpc, b.ha_entero, b.ha_ecoli, b.ha_salmonella
FROM tbl_header a
JOIN tbl_detail b ON a.headerid = b.headerid
),
resulttable AS (
SELECT tmp_date.sampling_date, tmp_detail.sampling_point, tmp_detail.sampling_type,
-- Case of Filling Room
CASE
WHEN tmp_detail.sampling_point ~* '.*(fr).*' AND tmp_detail.sampling_type = 'Personil' THEN tmp_detail.sampling_point
ELSE NULL
END AS fr_name,
CASE
WHEN tmp_detail.sampling_point ~* '.*(fr).*' AND tmp_detail.sampling_type = 'Personil' THEN tmp_detail.ha_tpc
ELSE NULL
END AS fr_tpc,
CASE
WHEN tmp_detail.sampling_point ~* '.*(fr).*' AND tmp_detail.sampling_type = 'Personil' THEN tmp_detail.ha_entero
ELSE NULL
END AS fr_entero,
CASE
WHEN tmp_detail.sampling_point ~* '.*(fr).*' AND tmp_detail.sampling_type = 'Personil' THEN tmp_detail.ha_ecoli
ELSE NULL
END AS fr_ecoli,
CASE
WHEN tmp_detail.sampling_point ~* '.*(fr).*' AND tmp_detail.sampling_type = 'Personil' THEN tmp_detail.ha_salmonella
ELSE NULL
END AS fr_salmo,
-- Case of Hopper Auger Filling
CASE
WHEN (tmp_detail.sampling_point ~* '.*(flex).*' OR tmp_detail.sampling_point ~* '.*(HPM).*') AND tmp_detail.sampling_type = 'Personil' THEN tmp_detail.sampling_point
ELSE NULL
END AS hpm_name,
CASE
WHEN (tmp_detail.sampling_point ~* '.*(flex).*' OR tmp_detail.sampling_point ~* '.*(HPM).*') AND tmp_detail.sampling_type = 'Personil' THEN tmp_detail.ha_tpc
ELSE NULL
END AS hpm_tpc,
CASE
WHEN (tmp_detail.sampling_point ~* '.*(flex).*' OR tmp_detail.sampling_point ~* '.*(HPM).*') AND tmp_detail.sampling_type = 'Personil' THEN tmp_detail.ha_entero
ELSE NULL
END AS hpm_entero,
CASE
WHEN (tmp_detail.sampling_point ~* '.*(flex).*' OR tmp_detail.sampling_point ~* '.*(HPM).*') AND tmp_detail.sampling_type = 'Personil' THEN tmp_detail.ha_ecoli
ELSE NULL
END AS hpm_ecoli,
CASE
WHEN (tmp_detail.sampling_point ~* '.*(flex).*' OR tmp_detail.sampling_point ~* '.*(HPM).*') AND tmp_detail.sampling_type = 'Personil' THEN tmp_detail.ha_salmonella
ELSE NULL
END AS hpm_salmo
FROM tmp_date
FULL JOIN tmp_detail ON tmp_date.sampling_date = tmp_detail.sampling_date
WHERE
tmp_detail.sampling_area = 'CMP' AND
tmp_detail.sampling_type = 'Personil' AND
(
tmp_detail.sampling_point ~* ANY ( VALUES ('(fr)'), ('(flex)'), ('(HPM)') )
)
)
SELECT
resulttable.sampling_date,
max(resulttable.sampling_type) AS sampling_type,
max(resulttable.fr_name) AS fr_name,
max(resulttable.fr_tpc) AS fr_tpc,
max(resulttable.fr_entero) AS fr_entero,
max(resulttable.fr_ecoli) AS fr_ecoli,
max(resulttable.fr_salmo) AS fr_salmonella,
max(resulttable.hpm_name) AS hopper_name,
max(resulttable.hpm_tpc) AS hopper_tpc,
max(resulttable.hpm_entero) AS hopper_entero,
max(resulttable.hpm_ecoli) AS hopper_ecoli,
max(resulttable.hpm_salmo) AS hopper_salmonella
FROM resulttable
GROUP BY resulttable.sampling_date ORDER BY resulttable.sampling_date;
我不知道为什么这些查询只返回1行,是因为我使用了GROUP BY
?:
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
sampling_date | sampling_type | fr_name | fr_tpc | fr_entero | fr_ecoli | fr_salmonella | hopper_name | hopper_tpc | hopper_entero | hopper_ecoli | hopper_salmonella |
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2016-12-09 | Personil | WT033 (FR) | 250 | 50 | Abs | Abs | BOIL013 (OPERATOR ENFLEX) | 500 | 50 | Abs | Abs |
我实际上想得到如下结果:
===================== Case of Filling Room =========================== | ===================== Case of Hopper Auger Filling ============================
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
sampling_date | sampling_type | fr_name | fr_tpc | fr_entero | fr_ecoli | fr_salmonella | hopper_name | hopper_tpc | hopper_entero | hopper_ecoli | hopper_salmonella |
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2016-12-09 | Personil | WT033 (FR) | 250 | 50 | Abs | Abs | BOIL013 (OPERATOR ENFLEX) | 500 | 50 | Abs | Abs |
2016-12-09 | Personil | | | | | | MP115 (OPR ENFLEX) | 300 | 50 | Abs | Abs |
任何帮助将不胜感激,谢谢。
答案 0 :(得分:1)
您的问题是您的GROUP BY
子句指定的标准不够具体,无法满足您的需求。由于您只有一个采样日期,因此只能输出一行。
阅读您的输出,我想您想要将hopper_name添加到GROUP BY
条款中。但是,你并不是100%清楚自己要做什么,所以理解这个条款和其他替代方案可能很重要。
没有分组的GROUP BY
目前您正在做的事情。它基本上说,对于在此标准中唯一的每一行,返回一行。这可能就是你想要的。因此,请确保您在此处有GROUP BY完全符合您的要求。
替代方案:使用汇总和多维数据集进行分组设置
要注意的一个复杂解决方案是,PostgreSQL允许您根据条件设置多个分组集并进行汇总。如果ROLLUP
无法让您到达目的地,那么可能想要查看CUBE
或GROUP BY
。但是,这会使检索数据的过程变得复杂,因为您希望获得分组列的位图。但是,由于您正在尝试使用数据透视表,因此可能需要注意进一步的步骤(以及指向其他步骤)。