将具有不同值的两行连接在一行中
Posted
技术标签:
【中文标题】将具有不同值的两行连接在一行中【英文标题】:join two rows with different values in a single row 【发布时间】:2019-09-02 09:58:21 【问题描述】:在一行中获取两条记录
尝试了子句 group by 却没有得到想要的结果。
我有三个表:direccion
、punto_suministro
、r_servicio_punto_suministro
。
id_direccion others_fields
10 XXX
10 YYY
id_punto_suministro id_r_servicio_punto_suministro
6 1
7 2
id_r_servicio_punto_suministro id_servicio_gas id_servicio_luz
1 6 null
2 null 7
查询:
SELECT
punto_suministro.id_direccion,
CASE WHEN r_servicio_punto_suministro.id_servicio_gas IS NOT NULL THEN punto_suministro.id_punto_suministro END AS Gas,
CASE WHEN r_servicio_punto_suministro.id_servicio_luz IS NOT NULL THEN punto_suministro.id_punto_suministro END AS Luz
FROM
direccion
LEFT JOIN punto_suministro ON direccion.id_direccion = punto_suministro.id_direccion
LEFT JOIN r_servicio_punto_suministro ON punto_suministro.id_r_servicio_punto_suministro = r_servicio_punto_suministro.id_r_servicio_punto_suministro
LEFT JOIN servicio_gas ON r_servicio_punto_suministro.id_servicio_gas = servicio_gas.id_servicio_gas
LEFT JOIN servicio_luz ON r_servicio_punto_suministro.id_servicio_luz = servicio_luz.id_servicio_luz
WHERE direccion.id_direccion = 10;
查询返回两行:
id_direccion Gas Luz
10 6 null
10 null 7
我想要一条记录中的结果:
id_direccion Gas Luz
10 6 7
【问题讨论】:
使用GROUP BY
和max()
进行聚合
【参考方案1】:
您可以使用条件聚合。您只需要修改您的查询以使用诸如MAX()
之类的聚合函数包围CASE
s(MIN()
也可以完成这项工作),并在末尾添加一个GROUP BY
子句:
SELECT
punto_suministro.id_direccion,
MAX(CASE WHEN r_servicio_punto_suministro.id_servicio_gas IS NOT NULL THEN punto_suministro.id_punto_suministro END) AS Gas,
MAX(CASE WHEN r_servicio_punto_suministro.id_servicio_luz IS NOT NULL THEN punto_suministro.id_punto_suministro END) AS Luz
FROM
direccion
LEFT JOIN punto_suministro ON direccion.id_direccion = punto_suministro.id_direccion
LEFT JOIN r_servicio_punto_suministro ON punto_suministro.id_r_servicio_punto_suministro = r_servicio_punto_suministro.id_r_servicio_punto_suministro
LEFT JOIN servicio_gas ON r_servicio_punto_suministro.id_servicio_gas = servicio_gas.id_servicio_gas
LEFT JOIN servicio_luz ON r_servicio_punto_suministro.id_servicio_luz = servicio_luz.id_servicio_luz
WHERE direccion.id_direccion = 10
GROUP BY punto_suministro.id_direccion;
【讨论】:
【参考方案2】:一般来说,使用LEFT JOIN
和聚合,您希望按第一个表中的值进行聚合。
因为您使用的是LEFT JOIN
,所以我猜您希望即使WHERE
子句上没有匹配项也希望返回一行。
为确保只有一行,请使用聚合查询 *不带GROUP BY
:
SELECT MAX(d.id_direccion) as id_direccion,
MAX(CASE WHEN sps.id_servicio_gas IS NOT NULL THEN ps.id_punto_suministro END) AS Gas,
MAX(CASE WHEN sps.id_servicio_luz IS NOT NULL THEN ps.id_punto_suministro END) AS Luz
FROM direccion d LEFT JOIN
punto_suministro ps
ON d.id_direccion = ps.id_direccion LEFT JOIN
r_servicio_punto_suministro sps
ON ps.id_r_servicio_punto_suministro = sps.id_r_servicio_punto_suministro LEFT JOIN
servicio_gas sg
ON sps.id_servicio_gas = sg.id_servicio_gas LEFT JOIN
servicio_luz sl
ON spm.id_servicio_luz = sl.id_servicio_luz
WHERE d.id_direccion = 10;
如果你知道10
存在于数据中,那么你可以使用GROUP BY d.id_direccion
。
【讨论】:
【参考方案3】:感谢您的回答。 我终于用连接修复了它:
SELECT
direccion.id_direccion,
cups_gas.id_punto_suministro AS Gas,
cups_luz.id_punto_suministro AS Luz
FROM
direccion
INNER JOIN
(SELECT
cups,
id_direccion,
punto_suministro.id_punto_suministro,
atr,
ca,
fecha_fin
FROM
punto_suministro
INNER JOIN r_servicio_punto_suministro ON r_servicio_punto_suministro.id_r_servicio_punto_suministro = punto_suministro.id_r_servicio_punto_suministro
INNER JOIN servicio_gas ON r_servicio_punto_suministro.id_servicio_gas = servicio_gas.id_servicio_gas
INNER JOIN r_contrato_punto_suministro ON punto_suministro.id_punto_suministro = r_contrato_punto_suministro.id_punto_suministro
INNER JOIN contrato ON r_contrato_punto_suministro.id_contrato = contrato.id_contrato
INNER JOIN r_servicio_contrato ON contrato.id_contrato = r_servicio_contrato.id_contrato
INNER JOIN servicio ON r_servicio_contrato.id_servicio = servicio.id_servicio) cups_gas ON direccion.id_direccion = cups_gas.id_direccion
INNER JOIN
(SELECT
cups,
id_direccion,
punto_suministro.id_punto_suministro,
atr,
ca,
fecha_fin
FROM
punto_suministro
INNER JOIN r_servicio_punto_suministro ON r_servicio_punto_suministro.id_r_servicio_punto_suministro = punto_suministro.id_r_servicio_punto_suministro
INNER JOIN servicio_luz ON r_servicio_punto_suministro.id_servicio_luz = servicio_luz.id_servicio_luz
INNER JOIN r_contrato_punto_suministro ON punto_suministro.id_punto_suministro = r_contrato_punto_suministro.id_punto_suministro
INNER JOIN contrato ON r_contrato_punto_suministro.id_contrato = contrato.id_contrato
INNER JOIN r_servicio_contrato ON contrato.id_contrato = r_servicio_contrato.id_contrato
INNER JOIN servicio ON r_servicio_contrato.id_servicio = servicio.id_servicio) cups_luz ON direccion.id_direccion = cups_luz.id_direccion
WHERE
direccion.id_direccion = 10;
最好的尊重。
【讨论】:
以上是关于将具有不同值的两行连接在一行中的主要内容,如果未能解决你的问题,请参考以下文章