SQL查询以获取2日期有效时间表之间的数据

时间:2019-07-23 14:05:51

标签: mysql sql

当玛格丽特担任经理时,我需要获取乔治·费斯托的薪水数据。

这是位置(标题表)表:

___________________________________________________
| name      | title     | from_date   | to_date    |
----------------------------------------------------
| Margareta | Manager   | 1985-01-01  | 1991-10-01 |

这是员工薪水表:

___________________________________________________
| name         | salary   | from_date   | to_date  |
----------------------------------------------------
Georgi Facello      60117   1986-06-26  1987-06-26
Georgi Facello      62102   1987-06-26  1988-06-25
Georgi Facello      66074   1988-06-25  1989-06-25
Georgi Facello      66596   1989-06-25  1990-06-25
Georgi Facello      66961   1990-06-25  1991-06-25
Georgi Facello      71046   1991-06-25  1992-06-24
Georgi Facello      74333   1992-06-24  1993-06-24
Georgi Facello      75286   1993-06-24  1994-06-24
Georgi Facello      75994   1994-06-24  1995-06-24
Georgi Facello      76884   1995-06-24  1996-06-23
Georgi Facello      80013   1996-06-23  1997-06-23
Georgi Facello      81025   1997-06-23  1998-06-23
Georgi Facello      81097   1998-06-23  1999-06-23
Georgi Facello      84917   1999-06-23  2000-06-22
Georgi Facello      85112   2000-06-22  2001-06-22
Georgi Facello      85097   2001-06-22  2002-06-22
Georgi Facello      88958   2002-06-22  9999-01-01

所以我的查询是

SELECT employees.name, salaries.*
FROM salaries
INNER JOIN employees ON employees.emp_no = salaries.emp_no
WHERE salaries.from_date >= (
    SELECT titles.from_date
    FROM titles 
    JOIN employees ON employees.emp_no = titles.emp_no
    WHERE titles.title = 'manager' AND employees.name = 'margareta markovitch'
) 
AND salaries.to_date <= (
    SELECT titles.to_date
    FROM titles 
    JOIN employees ON employees.emp_no = titles.emp_no
    WHERE titles.title = 'manager' AND employees.name = 'margareta markovitch'
) 

这是结果

 ___________________________________________________
| name         | salary   | from_date   | to_date  |
----------------------------------------------------
Georgi Facello      60117   1986-06-26  1987-06-26
Georgi Facello      62102   1987-06-26  1988-06-25
Georgi Facello      66074   1988-06-25  1989-06-25
Georgi Facello      66596   1989-06-25  1990-06-25
Georgi Facello      66961   1990-06-25  1991-06-25

问题是结果中不包含一行:

Georgi Facello      71046   1991-06-25  1992-06-24

哪一个仍然有效,因为玛格丽塔(Margareta)直到91年八月仍是经理

您对这个问题有建议吗?

4 个答案:

答案 0 :(得分:1)

您非常亲密。只需要包括所有重叠的时期:

 SELECT DISTINCT employees.name, salaries.*
    FROM salaries
    INNER JOIN employees ON employees.emp_no = salaries.emp_no
    WHERE salaries.from_date < (
        SELECT titles.to_date
        FROM titles 
        JOIN employees ON employees.emp_no = titles.emp_no
        WHERE titles.title = 'manager' AND employees.name = 'margareta markovitch'
    ) 
    AND salaries.to_date > (
        SELECT titles.from_date
        FROM titles 
        JOIN employees ON employees.emp_no = titles.emp_no
        WHERE titles.title = 'manager' AND employees.name = 'margareta markovitch'
    ) 

答案 1 :(得分:1)

对PeterHe的替代答案,如果您只担心玛格丽塔担任经理期间是否开始一年,则仅与from_date进行比较,而忽略to_date:

SELECT employees.name, salaries.*
FROM salaries
INNER JOIN employees ON employees.emp_no = salaries.emp_no
WHERE salaries.from_date >= (
    SELECT titles.from_date
    FROM titles 
    JOIN employees ON employees.emp_no = titles.emp_no
    WHERE titles.title = 'manager' AND employees.name = 'margareta markovitch'
) 
AND salaries.from_date <= (
    SELECT titles.to_date
    FROM titles 
    JOIN employees ON employees.emp_no = titles.emp_no
    WHERE titles.title = 'manager' AND employees.name = 'margareta markovitch'
) 

这将返回在玛格丽塔担任经理期间一年开始的所有条目。

答案 2 :(得分:1)

如果您需要的代码更少...

DROP TABLE IF EXISTS titles;

CREATE TABLE titles
(name VARCHAR(12) NOT NULL 
,title VARCHAR(12) NOT NULL
,from_date DATE NOT NULL
,to_date DATE NOT NULL
);


INSERT INTO titles VALUES
('Margareta','Manager','1985-01-01','1991-10-01');

DROP TABLE IF EXISTS salaries;

CREATE TABLE salaries
(name VARCHAR(30) NOT NULL 
,salary INT NOT NULL
,from_date DATE NOT NULL
,to_date DATE NOT NULL
,PRIMARY KEY(name,from_date)
);

INSERT INTO salaries VALUES
('Georgi Fecello',60117,'1986-06-26','1987-06-26'),
('Georgi Fecello',62102,'1987-06-26','1988-06-25'),
('Georgi Fecello',66074,'1988-06-25','1989-06-25'),
('Georgi Fecello',66596,'1989-06-25','1990-06-25'),
('Georgi Fecello',66961,'1990-06-25','1991-06-25'),
('Georgi Fecello',71046,'1991-06-25','1992-06-24'),
('Georgi Fecello',74333,'1992-06-24','1993-06-24'),
('Georgi Fecello',75286,'1993-06-24','1994-06-24'),
('Georgi Fecello',75994,'1994-06-24','1995-06-24'),
('Georgi Fecello',76884,'1995-06-24','1996-06-23'),
('Georgi Fecello',80013,'1996-06-23','1997-06-23'),
('Georgi Fecello',81025,'1997-06-23','1998-06-23'),
('Georgi Fecello',81097,'1998-06-23','1999-06-23'),
('Georgi Fecello',84917,'1999-06-23','2000-06-22'),
('Georgi Fecello',85112,'2000-06-22','2001-06-22'),
('Georgi Fecello',85097,'2001-06-22','2002-06-22');

SELECT s.* 
  FROM titles t 
  JOIN salaries s 
    ON s.from_date <= t.to_date 
   AND s.to_date >= t.from_date;
+----------------+--------+------------+------------+
| name           | salary | from_date  | to_date    |
+----------------+--------+------------+------------+
| Georgi Fecello |  60117 | 1986-06-26 | 1987-06-26 |
| Georgi Fecello |  62102 | 1987-06-26 | 1988-06-25 |
| Georgi Fecello |  66074 | 1988-06-25 | 1989-06-25 |
| Georgi Fecello |  66596 | 1989-06-25 | 1990-06-25 |
| Georgi Fecello |  66961 | 1990-06-25 | 1991-06-25 |
| Georgi Fecello |  71046 | 1991-06-25 | 1992-06-24 |
+----------------+--------+------------+------------+

答案 3 :(得分:0)

您可以分隔所有日期,并检查该表中的日期是:

DECLARE @employees TABLE
(
    emp_no INT,
    name NVARCHAR(MAX),
    title NVARCHAR(MAX),
    from_date DATE,
    to_date DATE
)

DECLARE @salaries TABLE
(
    emp_no INT,
    salary INT,
    from_date DATE,
    to_date DATE
)

INSERT INTO @employees VALUES
(1,'Margareta','Manager','1985-01-01','1991-10-01'),
(2,'Georgi Facello','Employee','1986-06-26','2002-06-22')

INSERT INTO @salaries VALUES
(2,60117,'1986-06-26','1987-06-26'),
(2,62102,'1987-06-26','1988-06-25'),
(2,66074,'1988-06-25','1989-06-25'),
(2,66596,'1989-06-25','1990-06-25'),
(2,66961,'1990-06-25','1991-06-25'),
(2,71046,'1991-06-25','1992-06-24'),
(2,74333,'1992-06-24','1993-06-24'),
(2,75286,'1993-06-24','1994-06-24'),
(2,75994,'1994-06-24','1995-06-24'),
(2,76884,'1995-06-24','1996-06-23'),
(2,80013,'1996-06-23','1997-06-23'),
(2,81025,'1997-06-23','1998-06-23'),
(2,81097,'1998-06-23','1999-06-23'),
(2,84917,'1999-06-23','2000-06-22'),
(2,85112,'2000-06-22','2001-06-22'),
(2,85097,'2001-06-22','2002-06-22')

DECLARE @from_date DATE = (SELECT from_date FROM @employees WHERE title = 'Manager' AND name = 'Margareta')
DECLARE @to_date DATE = (SELECT to_date FROM @employees WHERE title = 'Manager' AND name = 'Margareta')

DECLARE @dates TABLE ( singleDate DATE )

INSERT INTO @dates
SELECT  TOP (DATEDIFF(DAY, @from_date, @to_date) + 1)
        Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @from_date)
FROM    sys.all_objects a
        CROSS JOIN sys.all_objects b

SELECT E.name,S.* FROM @salaries S
LEFT JOIN @employees E ON S.emp_no = E.emp_no
WHERE S.from_date IN (SELECT singleDate FROM @dates)
OR S.to_date IN (SELECT singleDate FROM @dates)

输出:

name    emp_no  salary  from_date   to_date
Georgi Facello  2   60117   1986-06-26  1987-06-26
Georgi Facello  2   62102   1987-06-26  1988-06-25
Georgi Facello  2   66074   1988-06-25  1989-06-25
Georgi Facello  2   66596   1989-06-25  1990-06-25
Georgi Facello  2   66961   1990-06-25  1991-06-25
Georgi Facello  2   71046   1991-06-25  1992-06-24