我的模式:
CREATE TABLE employees
(`emp_no` int not null primary key)
;
INSERT INTO employees
(`emp_no`)
VALUES
(10001),
(10002),
(10003),
(10004),
(10005),
(10006),
(10007),
(10008),
(10009),
(10010)
;
CREATE TABLE departments
(`dept_no` varchar(4) not null primary key)
;
INSERT INTO departments
(`dept_no`)
VALUES
('d009'),
('d005'),
('d002'),
('d003'),
('d001'),
('d004'),
('d006'),
('d008'),
('d007'),
('d010')
;
CREATE TABLE `dept_emp` (
`emp_no` int(11) NOT NULL,
`dept_no` char(4) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`),
KEY `dept_no` (`dept_no`),
CONSTRAINT `dept_emp_ibfk_1` FOREIGN KEY (`emp_no`) REFERENCES `employees` (`emp_no`) ON DELETE CASCADE,
CONSTRAINT `dept_emp_ibfk_2` FOREIGN KEY (`dept_no`) REFERENCES `departments` (`dept_no`) ON DELETE CASCADE
);
INSERT INTO dept_emp
(`emp_no`, `dept_no`, `from_date`, `to_date`)
VALUES
(10001, 'd005', '1986-06-26 00:00:00', '2000-01-01 00:00:00'),
(10001, 'd006', '2000-01-01 00:00:00', '2002-01-01 00:00:00'),
(10001, 'd009', '2002-01-01 00:00:00', '2003-01-01 00:00:00'),
(10001, 'd001', '2003-01-01 00:00:00', '2009-01-01 00:00:00'),
(10002, 'd007', '1996-08-03 00:00:00', '2001-01-01 00:00:00'),
(10002, 'd006', '2001-01-01 00:00:00', '2002-01-01 00:00:00'),
(10002, 'd009', '2002-01-01 00:00:00', '2003-01-01 00:00:00'),
(10002, 'd008', '2003-01-01 00:00:00', '2003-06-01 00:00:00'),
(10002, 'd001', '2003-06-01 00:00:00', '2004-09-01 00:00:00'),
(10002, 'd002', '2004-06-01 00:00:00', '2005-09-01 00:00:00'),
(10002, 'd003', '2005-09-01 00:00:00', '2006-09-01 00:00:00'),
(10002, 'd010', '2006-09-01 00:00:00', '2010-09-01 00:00:00'),
(10003, 'd004', '1995-12-03 00:00:00', '1996-12-03 00:00:00'),
(10003, 'd005', '1996-12-03 00:00:00', '1997-12-03 00:00:00'),
(10003, 'd001', '1997-12-03 00:00:00', '2002-06-03 00:00:00'),
(10004, 'd004', '1986-12-01 00:00:00', '2000-01-01 00:00:00'),
(10004, 'd008', '2000-01-01 00:00:00', '2003-01-01 00:00:00'),
(10004, 'd005', '2003-01-01 00:00:00', '2005-01-01 00:00:00'),
(10005, 'd003', '1989-09-12 00:00:00', '2000-01-01 00:00:00'),
(10005, 'd002', '2000-01-01 00:00:00', '2003-06-01 00:00:00'),
(10005, 'd006', '2003-06-01 00:00:00', '2009-06-01 00:00:00'),
(10006, 'd005', '1990-08-05 00:00:00', '9999-01-01 00:00:00'),
(10007, 'd008', '1989-02-10 00:00:00', '2000-01-01 00:00:00'),
(10007, 'd007', '2000-01-01 00:00:00', '2003-01-01 00:00:00'),
(10007, 'd009', '2003-01-01 00:00:00', '2009-01-01 00:00:00'),
(10008, 'd005', '1998-03-11 00:00:00', '2000-07-31 00:00:00'),
(10008, 'd001', '2000-07-31 00:00:00', '2004-07-31 00:00:00'),
(10009, 'd006', '1985-02-18 00:00:00', '2002-01-01 00:00:00'),
(10009, 'd007', '2002-02-18 00:00:00', '2003-01-01 00:00:00'),
(10009, 'd008', '2003-02-18 00:00:00', '2004-01-01 00:00:00'),
(10009, 'd005', '2004-02-18 00:00:00', '2005-01-01 00:00:00'),
(10009, 'd003', '2005-02-18 00:00:00', '2006-01-01 00:00:00'),
(10009, 'd002', '2006-02-18 00:00:00', '2007-01-01 00:00:00'),
(10009, 'd010', '2007-02-18 00:00:00', '2009-01-01 00:00:00')
;
我尝试了以下查询:
SELECT
e1.emp_no,
de1.dept_no,
e2.emp_no,
COUNT(DISTINCT de1.dept_no) Total
FROM
employees e1
JOIN
employees e2 ON e1.emp_no < e2.emp_no
JOIN
dept_emp de1 ON de1.emp_no = e1.emp_no
JOIN
dept_emp de2 ON de2.emp_no = e2.emp_no
AND de2.dept_no = de1.dept_no
AND de1.from_date <= de2.to_date
AND de2.from_date <= de1.to_date
GROUP BY e2.emp_no, e1.emp_no
HAVING Total > x;
输出:
| emp_no | dept_no | emp_no | Total |
|--------|---------|--------|-------|
| 10001 | d006 | 10002 | 3 |
| 10002 | d009 | 10007 | 2 |
| 10001 | d005 | 10008 | 2 |
| 10002 | d010 | 10009 | 4 |
该查询只是给我一个 dept_no 。
我想要它们一起出现的所有 dept_no 的列表,如下面的示例:
| emp_no | dept_no | emp_no | Total |
|--------|---------|--------|-------|
| 10001 | d006 | 10002 | 3 |
| 10001 | d001 | 10002 | 3 |
| 10001 | d009 | 10002 | 3 |
| 10002 | d009 | 10007 | 2 |
| 10002 | d007 | 10007 | 2 |
| 10001 | d005 | 10008 | 2 |
| 10001 | d001 | 10008 | 2 |
| 10002 | d010 | 10009 | 4 |
| 10002 | d008 | 10009 | 4 |
| 10002 | d003 | 10009 | 4 |
| 10002 | d006 | 10009 | 4 |
答案 0 :(得分:0)
您的查询看起来不错,但是聚合使事情变得混乱。在MySQL 8.0中,您可以摆脱聚合并在内部查询中进行窗口计数。然后外部查询根据计数进行过滤。
SELECT *
FROM (
SELECT
e1.emp_no emp_no1,
de1.dept_no,
e2.emp_no emp_no2,
COUNT(*) OVER(PARTITION BY e1.emp_no, e2.emp_no) cnt
FROM
employees e1
JOIN
employees e2 ON e1.emp_no < e2.emp_no
JOIN
dept_emp de1 ON de1.emp_no = e1.emp_no
JOIN
dept_emp de2 ON de2.emp_no = e2.emp_no
AND de2.dept_no = de1.dept_no
AND de1.from_date <= de2.to_date
AND de2.from_date <= de1.to_date
) x
WHERE cnt > 1
ORDER BY emp_no1, emp_no2, dept_no
| emp_no1 | dept_no | emp_no2 | cnt |
| ------- | ------- | ------- | --- |
| 10001 | d001 | 10002 | 3 |
| 10001 | d006 | 10002 | 3 |
| 10001 | d009 | 10002 | 3 |
| 10001 | d001 | 10008 | 2 |
| 10001 | d005 | 10008 | 2 |
| 10002 | d007 | 10007 | 2 |
| 10002 | d009 | 10007 | 2 |
| 10002 | d003 | 10009 | 4 |
| 10002 | d006 | 10009 | 4 |
| 10002 | d008 | 10009 | 4 |
| 10002 | d010 | 10009 | 4 |
答案 1 :(得分:0)
您可以使用GROUP_CONCAT()
以逗号分隔的列表形式返回所有部门:
SELECT
e1.emp_no,
GROUP_CONCAT(de1.dept_no) as dept_nos,
e2.emp_no,
COUNT(DISTINCT de1.dept_no) Total
FROM
employees e1
JOIN
employees e2 ON e1.emp_no < e2.emp_no
JOIN
dept_emp de1 ON de1.emp_no = e1.emp_no
JOIN
dept_emp de2 ON de2.emp_no = e2.emp_no
AND de2.dept_no = de1.dept_no
AND de1.from_date <= de2.to_date
AND de2.from_date <= de1.to_date
GROUP BY e2.emp_no, e1.emp_no
HAVING Total > 1;
结果:
| emp_no | dept_nos | Total | emp_no |
| ------ | ------------------- | ----- | ------ |
| 10001 | d006,d009,d001 | 3 | 10002 |
| 10002 | d009,d007 | 2 | 10007 |
| 10001 | d005,d001 | 2 | 10008 |
| 10002 | d008,d010,d003,d006 | 4 | 10009 |
这看起来与您的预期结果有所不同,但是它以更紧凑的形式包含了相同的信息。
请注意,您的原始查询是不确定的,并且在启用ONLY_FULL_GROUP_BY
模式时会导致错误,这是自MySQL 5.7起的默认设置。
如果您不需要employees
表中的任何数据,也不需要查询它们。
SELECT
de1.emp_no,
GROUP_CONCAT(de1.dept_no) as dept_nos,
de2.emp_no,
COUNT(DISTINCT de1.dept_no) Total
FROM
dept_emp de1
JOIN
dept_emp de2
ON de2.dept_no = de1.dept_no
AND de2.emp_no > de1.emp_no
AND de1.from_date <= de2.to_date
AND de2.from_date <= de1.to_date
GROUP BY de2.emp_no, de1.emp_no
HAVING Total > 1;
这将返回相同的结果。