首页 > 解决方案 > 如何在 MySQL 中显示所有结果,不包括特定行中多个项目共享的结果?

问题描述

我需要出示公寓(单位)的费用清单。一些公寓将承担所有费用,而一些公寓仅承担少数费用。我需要区分哪些贡献了什么。

请参阅此小提琴以获取完整演示:http ://sqlfiddle.com/#!9/6d508a/1 从以下查询中,我只想查看没有多个链接费用单位的记录

SELECT idGasto, gastos.idRubro, monto, rubros.nombre, GROUP_CONCAT(tiposUF.nombre)
FROM gastos
LEFT JOIN rubros ON gastos.idRubro = rubros.idRubro
LEFT JOIN tipoUFRubros ON gastos.idRubro = tipoUFRubros.idRubro
LEFT JOIN tiposUF ON tipoUFRubros.idTipoUF = tiposUF.idTipoUF
GROUP BY gastos.idGasto

结果是:

伊德加斯托 idRubro 蒙托 名词 GROUP_CONCAT(tiposUF.nombre)
1 6 1000 赔偿 部门
2 4 100 酬金管理 部门,本地
3 6 500 赔偿 部门

我想排除结果,idGasto=2因为它有多个链接rubros记录。

预期结果

伊德加斯托 idRubro 蒙托 名词 GROUP_CONCAT(tiposUF.nombre)
1 6 1000 赔偿 部门
3 6 500 赔偿 部门

我尝试了以下方法,但这仅限制了链接的记录,我不必指定特定的 Id

SELECT idGasto, gastos.idRubro, monto, rubros.nombre, GROUP_CONCAT(tiposUF.nombre)
FROM gastos
LEFT JOIN rubros ON gastos.idRubro = rubros.idRubro
LEFT JOIN tipoUFRubros ON gastos.idRubro = tipoUFRubros.idRubro
LEFT JOIN tiposUF ON tipoUFRubros.idTipoUF = tiposUF.idTipoUF
WHERE tiposUF.idTipoUF = 1
AND tiposUF.idTipoUF NOT IN (
    SELECT idGasto
    FROM gastos 
    JOIN tipoUFRubros ON gastos.idRubro = tipoUFRubros.idRubro
    JOIN tiposUF ON tiposUF.idTipoUF = tipoUFRubros.idTipoUF
    WHERE tiposUF.idTipoUF = 2
)
GROUP BY gastos.idGasto

失败的结果: http ://sqlfiddle.com/#!9/6d508a/2

伊德加斯托 idRubro 蒙托 名词 GROUP_CONCAT(tiposUF.nombre)
1 6 1000 赔偿 部门
2 4 100 酬金管理 部门
3 6 500 赔偿 部门

以下是架构和设置脚本:

-- List of type of units that have to pay the expenses
CREATE TABLE tiposUF(
    idTipoUF int unsigned not null auto_increment primary key,
    nombre varchar(250) null
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `tiposUF` (`nombre`) VALUES
('Departamento'),
('Local');

-- type of expenses
CREATE TABLE rubros(
    idRubro int unsigned not null auto_increment primary key,
    nombre varchar(250) null
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `rubros` (`nombre`) VALUES
('Impuestos'),
('2'), -- not important
('3'), -- not important
('Honorarios Administracion'),
('5'), -- not important
('Reparaciones');

-- M:N Link between units and expenses
CREATE TABLE tipoUFRubros(
    idTipoUFRubro int unsigned not null auto_increment primary key,
    idRubro int not null,
    idTipoUF int not null
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO tipoUFRubros (idRubro,idTipoUF) VALUES
(1,1),
(2,1),
(3,1),
(4,1),
(5,1),
(6,1),
(2,2),
(3,2),
(4,2);

-- Expenses
CREATE TABLE gastos(
    idGasto int unsigned not null auto_increment primary key,
    idRubro int not null,
    monto int not null
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO gastos (idRubro, monto) VALUES
(6,1000),
(4,100),
(6,500);

标签: mysqlwhere-clause

解决方案


在分组结果集中,我们可以使用该HAVING子句针对该集合上的聚合函数应用过滤条件。在这种情况下,您只希望一个小于 2 的结果:COUNThttp ://sqlfiddle.com/# !9/6d508a/3tiposUF.nombre

SELECT idGasto, gastos.idRubro, monto, rubros.nombre, GROUP_CONCAT(tiposUF.nombre)
FROM gastos
LEFT JOIN rubros ON gastos.idRubro = rubros.idRubro
LEFT JOIN tipoUFRubros ON gastos.idRubro = tipoUFRubros.idRubro
LEFT JOIN tiposUF ON tipoUFRubros.idTipoUF = tiposUF.idTipoUF
GROUP BY gastos.idGasto
HAVING COUNT(tiposUF.nombre) < 2

结果:

伊德加斯托 idRubro 蒙托 名词 GROUP_CONCAT(tiposUF.nombre)
1 6 1000 赔偿 部门
3 6 500 赔偿 部门

推荐阅读