左连接的多个分组不起作用

时间:2015-08-09 18:09:24

标签: mysql join group-by

我试图解决这个问题好几天,但没有成功。我希望你的专业知识:

分组我希望实现,同样位于:http://imgur.com/q8qoAVQ enter image description here

示例 sqlfiddle http://sqlfiddle.com/#!9/e42e6/2

DDL和示例数据

CREATE TABLE tx_management_domain_model_events (
    `uid` int(11) NOT NULL,
    `title` varchar(255),
    PRIMARY KEY(uid)
);

CREATE TABLE tx_management_domain_model_programm (
    `uid` int(11) NOT NULL,
    `jobtype` int(11) unsigned DEFAULT '0' NOT NULL,
    `reservation` int(11) DEFAULT '0' NOT NULL,
    `eventdate` date NULL,
    `event` int(11) DEFAULT '0' NOT NULL,
    PRIMARY KEY(uid)
);

CREATE TABLE tx_management_domain_model_reservations (
    `uid` int(11) NOT NULL,
    `event` int(11) default '0',
    `feuser` int(11) DEFAULT '0',
    `status` int(11) DEFAULT '0' NOT NULL,
    `ressource` int(11) DEFAULT '0',
    PRIMARY KEY(uid)
);

CREATE TABLE tx_management_domain_model_appointments (
    `uid` int(11) NOT NULL,
    `begin` int(11) DEFAULT '0' NOT NULL,
    `end` int(11) DEFAULT '0' NOT NULL,
    `event` int(11) unsigned DEFAULT '0' NOT NULL,
    PRIMARY KEY(uid)
);

CREATE TABLE tx_management_domain_model_additionalcosts (
    `uid` int(11) NOT NULL,
    `additionalcosttype` int(11) unsigned DEFAULT '0' NOT NULL,
    `event` int(11) DEFAULT '0' NOT NULL,
    `feuser` int(11) DEFAULT '0' NOT NULL,
    `reservation` int(11) DEFAULT '0' NOT NULL,
    PRIMARY KEY (uid)
);

CREATE TABLE tx_management_domain_model_referents (
    `uid` int(11) NOT NULL,
    `specialsallary` text NULL,
    `feuser` int(11) unsigned DEFAULT '0' NOT NULL,
    `event` int(11) unsigned DEFAULT '0' NOT NULL,  
    PRIMARY KEY(uid)
);

CREATE TABLE fe_users (
    `uid` int(11) NOT NULL,
    `fullname` varchar(255),
    PRIMARY KEY(uid)
);

# ---------------------- Fill with data --------------------
INSERT INTO tx_management_domain_model_events
    (`uid`, `title`)
VALUES
    (1660, 'Event-1'),
    (1632, 'Event-2');

INSERT INTO tx_management_domain_model_programm
    (`uid`, `jobtype`, `reservation`, `event`, `eventdate`)
VALUES
    (1149, 2, 11259, 1660, '2015-05-04'),
    (1154, 0, 11278, 1660, '2015-05-04'),
    (1534, 0, 11783, 1660, '2015-07-11');

INSERT INTO tx_management_domain_model_reservations
    (`uid`, `event`, `feuser`, `status`, `ressource`)
VALUES
    (11259, 1660, 116740, 1105, 19901),
    (11278, 1660, 116740, 1105, 19901),
    (11280, 1660, 117354, 1101, 19902),
    (11783, 1660, 116740, 1101, 19901),
    (11784, 1660, 116740, 1101, 100001);

INSERT INTO tx_management_domain_model_appointments
    (`uid`, `begin`, `end`, `event`)
VALUES
    (1104, 1430690400, 1432936800, 1660),
    (1123, 1436565600, 1436652000, 1660),
    (1127, 1436306400, 1436911200, 1632);

INSERT INTO tx_management_domain_model_additionalcosts
    (`uid`, `additionalcosttype`, `event`, `feuser`, `reservation`)
VALUES
    (1, 0, 1660, 11740, 11784);

INSERT INTO tx_management_domain_model_referents
    (`uid`, `specialsallary`, `feuser`, `event`)
VALUES
    (1885, '', 116740, 1660),
    (1935, '', 116740, 1632);

INSERT INTO fe_users
    (`uid`, `fullname`)
VALUES
    (116740, 'John Kohn');

SQL查询

select
    group_concat(distinct tbl_events.uid) as Event,
    date_format(from_unixtime(tbl_appointments.`begin`),get_format(DATE, 'EUR')) AS 'appointmentBegin',
    date_format(from_unixtime(tbl_appointments.`end`),get_format(DATE, 'EUR')) AS 'appointmentEnd',
    group_concat(distinct tbl_reservations.ressource) as Ressource,
    group_concat(distinct tbl_programm.jobtype) as Jobtyp,
    group_concat(tbl_reservations.uid) AS Reservations,
    group_concat(distinct tbl_referents.specialsallary) AS Specialsallary
from 
    tx_management_domain_model_events tbl_events
    inner join tx_management_domain_model_reservations as tbl_reservations on tbl_reservations.event = tbl_events.uid
    inner join tx_management_domain_model_appointments as tbl_appointments on tbl_events.uid = tbl_appointments.event
    left join tx_management_domain_model_programm as tbl_programm on tbl_reservations.uid = tbl_programm.reservation and tbl_programm.eventdate between from_unixtime(tbl_appointments.`begin`) and from_unixtime(tbl_appointments.`end`)
    left join tx_management_domain_model_additionalcosts as tbl_additionalcosts on tbl_reservations.uid = tbl_additionalcosts.reservation
    inner join fe_users on tbl_reservations.feuser = fe_users.uid
    inner join tx_management_domain_model_referents as tbl_referents on tbl_reservations.feuser = tbl_referents.feuser
where tbl_reservations.feuser = 116740
    and tbl_reservations.ressource in (19901,19902,100001,100002)
    and tbl_referents.event = tbl_events.uid
    and tbl_programm.event = tbl_events.uid
group by
    tbl_events.uid,
    CASE WHEN (tbl_reservations.ressource in (19901,19902,100001,100002) AND ((tbl_referents.specialsallary IS NULL) OR (tbl_referents.specialsallary LIKE ''))) THEN tbl_reservations.ressource ELSE tbl_referents.specialsallary END,
    from_unixtime(tbl_appointments.`begin`),
    from_unixtime(tbl_appointments.`end`),
    tbl_programm.jobtype;

问题:未显示tx_management_domain_model_additionalcosts中的所有记录。

预计:预订" 11784"也应该在结果栏中"预订"。

提示:如果我注释掉tbl_programm的每个WHERE条件,则会显示tbl_additionalcosts的记录。但为什么我必须删除这些条件?

有没有人知道我有错误的地方?

1 个答案:

答案 0 :(得分:0)

你在where子句中的一个条件是排除他的预约" 11784"见下文它是孤立的。

select
    tbl_reservations.uid
from 
    tx_management_domain_model_events tbl_events
    inner join tx_management_domain_model_reservations as tbl_reservations on tbl_reservations.event = tbl_events.uid
    inner join tx_management_domain_model_appointments as tbl_appointments on tbl_events.uid = tbl_appointments.event
    left join tx_management_domain_model_programm as tbl_programm on tbl_reservations.uid = tbl_programm.reservation and tbl_programm.eventdate between from_unixtime(tbl_appointments.`begin`) and from_unixtime(tbl_appointments.`end`)
    left join tx_management_domain_model_additionalcosts as tbl_additionalcosts on tbl_reservations.uid = tbl_additionalcosts.reservation
    inner join fe_users on tbl_reservations.feuser = fe_users.uid
    inner join tx_management_domain_model_referents as tbl_referents on tbl_reservations.feuser = tbl_referents.feuser
where tbl_reservations.feuser = 116740
    and tbl_reservations.ressource in (19901,19902,100001,100002)

    /* JOIN */
    and tbl_referents.event = tbl_events.uid

    /* JOIN & this condition excludes "11784"*/
    and tbl_programm.event = tbl_events.uid

order by
    tbl_reservations.uid

注意谓词和前面的谓词都是JOINING而不是过滤 所以,我的建议是将这两者都移到FROM子句

<强>结果

| Event | appointmentBegin | appointmentEnd | Ressource | Jobtyp | Reservations | Specialsallary |
|-------|------------------|----------------|-----------|--------|--------------|----------------|
|  1660 |       03.05.2015 |     29.05.2015 |    100001 | (null) |        11784 |                |
|  1660 |       10.07.2015 |     11.07.2015 |    100001 | (null) |        11784 |                |
|  1660 |       03.05.2015 |     29.05.2015 |     19901 | (null) |        11783 |                |
|  1660 |       03.05.2015 |     29.05.2015 |     19901 |      0 |        11278 |                |
|  1660 |       03.05.2015 |     29.05.2015 |     19901 |      2 |        11259 |                |
|  1660 |       10.07.2015 |     11.07.2015 |     19901 | (null) |  11259,11278 |                |
|  1660 |       10.07.2015 |     11.07.2015 |     19901 |      0 |        11783 |                |

按修改后的查询

select
    group_concat(distinct tbl_events.uid) as Event,
    date_format(from_unixtime(tbl_appointments.`begin`),get_format(DATE, 'EUR')) AS 'appointmentBegin',
    date_format(from_unixtime(tbl_appointments.`end`),get_format(DATE, 'EUR')) AS 'appointmentEnd',
    group_concat(distinct tbl_reservations.ressource) as Ressource,
    group_concat(distinct tbl_programm.jobtype) as Jobtyp,
    group_concat(tbl_reservations.uid) AS Reservations,
    group_concat(distinct tbl_referents.specialsallary) AS Specialsallary
from 
    tx_management_domain_model_events tbl_events
    inner join tx_management_domain_model_reservations as tbl_reservations on tbl_reservations.event = tbl_events.uid
    inner join tx_management_domain_model_appointments as tbl_appointments on tbl_events.uid = tbl_appointments.event
    left join tx_management_domain_model_programm as tbl_programm on tbl_reservations.uid = tbl_programm.reservation and tbl_programm.eventdate between from_unixtime(tbl_appointments.`begin`) and from_unixtime(tbl_appointments.`end`)
    and tbl_programm.event = tbl_events.uid

    left join tx_management_domain_model_additionalcosts as tbl_additionalcosts on tbl_reservations.uid = tbl_additionalcosts.reservation
    inner join fe_users on tbl_reservations.feuser = fe_users.uid
    inner join tx_management_domain_model_referents as tbl_referents on tbl_reservations.feuser = tbl_referents.feuser
    and tbl_referents.event = tbl_events.uid

where tbl_reservations.feuser = 116740
    and tbl_reservations.ressource in (19901,19902,100001,100002)
group by
    tbl_events.uid,
    CASE WHEN (tbl_reservations.ressource in (19901,19902,100001,100002) AND ((tbl_referents.specialsallary IS NULL) OR (tbl_referents.specialsallary LIKE ''))) THEN tbl_reservations.ressource ELSE tbl_referents.specialsallary END,
    from_unixtime(tbl_appointments.`begin`),
    from_unixtime(tbl_appointments.`end`),
    tbl_programm.jobtype;

注意:如果在外部联接连接的表的where子句中包含谓词,则可以非常轻松地覆盖该外部联接的效果,因此实际上它将成为内部联接。