我有两张这样的表:
表1
emp_leave_summary(id,emp_id,leave_from_date,leave_to_date,leave_type)
表2
emp_leave_daywise(id,emp_id,leave_date,leave_type)
我想从 Table1 中选择emp_id, leave_type
并插入 Table2 。
例如: 在表1中我有这个
id,emp_id,leave_from_date,leave_to_date,leave_type
1, 12345,2017-07-01 ,2017-07-03 ,Sick Leave
在表2中,我希望有这个
id,emp_id,leave_date,leave_type
1,12345,2017-07-01,Sick Leave
2,12345,2017-07-02,Sick Leave
3,12345,2017-07-03,Sick Leave
包含示例数据的表格结构
CREATE TABLE `emp_leave_summary` (
`id` int(11) NOT NULL,
`emp_id` int(11) NOT NULL,
`leave_from_date` date NOT NULL,
`leave_to_date` date NOT NULL,
`leave_type` varchar(30) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `emp_leave_summary` (`id`, `emp_id`, `leave_from_date`, `leave_to_date`, `leave_type`) VALUES
(1, 123, '2017-02-01', '2017-02-15', 'Earned Vacation Leave'),
(2, 123, '2017-07-12', '2017-07-26', 'Earned Vacation Leave'),
(3, 456, '2017-03-20', '2017-04-20', 'Earned Vacation Leave'),
(4, 789, '2017-01-15', '2017-02-23', 'Earned Vacation Leave'),
(5, 789, '2017-02-26', '2017-02-27', 'Sick Leave');
CREATE TABLE `emp_leave_daywise` (
`id` int(11) NOT NULL,
`emp_id` int(11) NOT NULL,
`leave_date` date NOT NULL,
`leave_type` varchar(30) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `emp_leave_daywise`
ADD PRIMARY KEY (`id`),
ADD KEY `emp_id` (`emp_id`),
ADD KEY `leave_date` (`leave_date`),
ADD KEY `leave_type` (`leave_type`);
ALTER TABLE `emp_leave_summary`
ADD PRIMARY KEY (`id`),
ADD KEY `emp_id` (`emp_id`),
ADD KEY `leave_type` (`leave_type`),
ADD KEY `leave_from_date` (`leave_from_date`),
ADD KEY `leave_to_date` (`leave_to_date`);
答案 0 :(得分:2)
尝试:
select * from
(select adddate('1970-01-01',t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) selected_date from
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) v
where selected_date between '2012-02-10' and '2012-02-15'
- 未来的日期范围可达近300年。
来自How to get list of dates between two dates in mysql select query
答案 1 :(得分:0)
我已设法使用以下解决方案获得首选输出
<强>步骤1 强>
创建一个日历表并插入日期(所有可能需要的日期),如下所示
CREATE TABLE `db_calender` (
`c_date` date NOT NULL);
然后将日期插入日历表,轻松插入我使用此How to populate a table with a range of dates?中回答的程序,感谢Mr.Leniel Macaferi。
DROP PROCEDURE IF EXISTS filldates;
DELIMITER |
CREATE PROCEDURE filldates(dateStart DATE, dateEnd DATE)
BEGIN
WHILE dateStart <= dateEnd DO
INSERT INTO tablename (_date) VALUES (dateStart);
SET dateStart = date_add(dateStart, INTERVAL 1 DAY);
END WHILE;
END;
| DELIMITER; CALL filldates('2017-02-01','2017-07-31');
然后我尝试在此查询下方获取首选输出
SELECT
els.*, c.c_date
FROM
emp_leave_summary els
JOIN db_calender c ON c.c_date BETWEEN els.leave_from_date AND els.leave_to_date
ORDER BY
els.id,c.c_date
我感谢大家的贡献和支持。
答案 2 :(得分:0)
感谢您的架构。它使您可以轻松处理您的问题。 我稍微改变了你的模式以使用auto_increment
CREATE TABLE `emp_leave_summary` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`emp_id` int(11) NOT NULL,
`leave_from_date` date NOT NULL,
`leave_to_date` date NOT NULL,
`leave_type` varchar(30) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `emp_leave_summary` (`emp_id`, `leave_from_date`, `leave_to_date`, `leave_type`) VALUES
( 123, '2017-02-01', '2017-02-15', 'Earned Vacation Leave'),
( 123, '2017-07-12', '2017-07-26', 'Earned Vacation Leave'),
( 456, '2017-03-20', '2017-04-20', 'Earned Vacation Leave'),
( 789, '2017-01-15', '2017-02-23', 'Earned Vacation Leave'),
( 789, '2017-02-26', '2017-02-27', 'Sick Leave');
CREATE TABLE `emp_leave_daywise` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`emp_id` int(11) NOT NULL,
`leave_date` date NOT NULL,
`leave_type` varchar(30) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
这里我在emp_leave_daywise表上添加了一个唯一约束,因为id整数上的主键不能确保记录不重复。
ALTER TABLE `emp_leave_daywise`
ADD UNIQUE KEY `emp_leave_daywise_unique_key` (`emp_id`,`leave_date`,`leave_type`),
ADD KEY `emp_id` (`emp_id`),
ADD KEY `leave_date` (`leave_date`),
ADD KEY `leave_type` (`leave_type`);
emp_leave_summary的唯一键需要一些思考。 例如......您是否允许包含重叠日期范围的摘要? ...
ALTER TABLE `emp_leave_summary`
ADD UNIQUE KEY `emp_leave_summary_unique_key` (`emp_id`,`leave_from_date`),
ADD KEY `emp_id` (`emp_id`),
ADD KEY `leave_type` (`leave_type`),
ADD KEY `leave_from_date` (`leave_from_date`),
ADD KEY `leave_to_date` (`leave_to_date`);
现在使用现有数据的左连接进行数据提取。
/*
insert any missing records using a left join on existing records
*/
insert into emp_leave_daywise ( emp_id, leave_date, leave_type )
select `new`.* from
(
select summary.emp_id, dates.date_ leave_date, summary.leave_type
from emp_leave_summary summary
inner join (
/*
get dates to match against
https://stackoverflow.com/questions/9295616/how-to-get-list-of-dates-between-two-dates-in-mysql-select-query
*/
select adddate('1970-01-01',t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) date_ from
( select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,
( select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,
( select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,
( select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,
( select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) dates
on dates.date_ >= summary.leave_from_date
and dates.date_ <= summary.leave_to_date
) `new`
left join emp_leave_daywise old
on `new`.emp_id = old.emp_id
and `new`.leave_date = old.leave_date
and `new`.leave_type = old.leave_type
where old.id is null ;
select * from emp_leave_daywise order by leave_date, emp_id;
根据给定的数据返回104行
id emp_id leave_date leave_type
1 789 2017-01-15 Earned Vacation Leave
2 789 2017-01-16 Earned Vacation Leave
3 789 2017-01-17 Earned Vacation Leave
4 789 2017-01-18 Earned Vacation Leave
5 789 2017-01-19 Earned Vacation Leave
6 789 2017-01-20 Earned Vacation Leave
...
102 123 2017-07-24 Earned Vacation Leave
103 123 2017-07-25 Earned Vacation Leave
104 123 2017-07-26 Earned Vacation Leave
日期范围创建SQL来自此处How to get list of dates between two dates in mysql select query