2015-12-31 39 views
5

Tôi có một tập hợp dữ liệu các dự án. Các dự án thay đổi trạng thái từ đầu đến cuối và ngày thay đổi trạng thái được ghi lại trong một bảng (bảng được đặt tên là "sự kiện" - không phải lựa chọn của tôi). Sẽ giống như thế này (được đơn giản hóa):MySQL Điền vào các ngày bị thiếu giữa hai ngày cho một trạng thái đã cho

Date  Status 
2015-06-01 Start 
2015-06-03 Stage 2 
2015-06-07 Stage 3 

Trong bất kỳ phạm vi ngày nào (được xác định động) Tôi muốn có thể xem dự án nào ở trạng thái nào. Tuy nhiên, bằng cách sử dụng GIỮA hoặc truy vấn khác chống lại dữ liệu sẽ chỉ kéo những dự án có trạng thái thay đổi trong khoảng thời gian đó, không phải các dự án vẫn ở trạng thái đã cho.

Tôi hiện đang tạo ra một giải pháp rất vụng về trong Excel mà các bản sao hàng vào hàng mới giữa ngày thay đổi trạng thái, như vậy:

Date   Status 
2015-06-01 Project start 
2015-06-02 Project start (copied) 
2015-06-03 Stage 2 
2015-06-04 Stage 2 (copied) 
2015-06-05 Stage 2 (copied) 
2015-06-06 Stage 2 (copied) 
2015-06-07 Stage 3 

Giải pháp này cho phép tôi để truy vấn trạng thái cho các dự án trên, nói , 2015-06-06 và thấy rằng nó vẫn còn ở Giai đoạn 2.

Có cách nào tôi có thể sử dụng mySql để kéo dữ liệu này giống nhau không, nhưng là đầu ra cho truy vấn? Tôi đã nghe một số đề nghị sử dụng một bảng Lịch, nhưng tôi không chắc chắn làm thế nào mà sẽ làm việc. Tôi cũng đã nhìn thấy một người nào đó đề nghị một Cross Join, nhưng một lần nữa, tôi không thể hiểu được từ mô tả như thế nào sẽ làm việc.

Cảm ơn trước sự giúp đỡ của bạn!

Trả lời

0

bạn không cần tạo bảng có tất cả các ngày. bạn có thể thay đổi bảng của mình để cung cấp ngày bắt đầu và ngày kết thúc cho từng trạng thái và sử dụng câu lệnh giữa.

hoặc sử dụng dữ liệu hiện có của bạn.

sử dụng @datequery làm ngày bạn muốn tìm trạng thái.

Select top 1 Status from Events 
where Date <= @datequery and Date 
order by Date desc 

trả về thay đổi trạng thái gần đây nhất trước ngày bạn đang truy vấn.

@datequery = 2015-06-06 

Status 
Stage 2 
1

kế hoạch

  • tạo bảng lịch bằng chữ số tham gia chéo và date_add trong giai đoạn lịch ..
  • tham gia dữ liệu của bạn với nguồn lịch với ngày < = ngày lịch
  • mất tối đa của ngày < = lịch ngày
  • tham gia trở lại nguồn dữ liệu gốc để có được tình trạng

thiết lập

drop table if exists calendar_t; 
CREATE TABLE calendar_t (
    id integer primary key auto_increment not null, 
    `date` date not null, 
    day varchar(9) not null, 
    month varchar(13) not null, 
    `year` integer not null 
); 

drop view if exists digits_v; 
create view digits_v 
as 
select 0 as n 
union all 
select 1 
union all 
select 2 
union all 
select 3 
union all 
select 4 
union all 
select 5 
union all 
select 6 
union all 
select 7 
union all 
select 8 
union all 
select 9 
; 

insert into calendar_t 
(`date`, day, month, `year`) 
select 
date_add('2015-01-01', interval 100*a2.n + 10*a1.n + a0.n day) as `date`, 
dayname(date_add('2015-01-01', interval 100*a2.n + 10*a1.n + a0.n day)) as day, 
monthname(date_add('2015-01-01', interval 100*a2.n + 10*a1.n + a0.n day)) as month, 
year(date_add('2015-01-01', interval 100*a2.n + 10*a1.n + a0.n day)) as `year` 
from 
digits_v a2 
cross join digits_v a1 
cross join digits_v a0 
order by date_add('2015-01-01', interval 100*a2.n + 10*a1.n + a0.n day) 
; 

drop table if exists example; 
create table example 
(
    `date` date not null, 
    status varchar(23) not null 
); 

insert into example 
(`date`, status) 
values 
('2015-06-01', 'Start' ), 
('2015-06-03', 'Stage 2'), 
('2015-06-07', 'Stage 3') 
; 

truy vấn

select cal_date, mdate, ex2.status 
from 
(
select cal_date, max(ex_date) as mdate 
from 
(
select cal.`date` as cal_date, ex.`date` as ex_date 
from calendar_t cal 
inner join example ex 
on ex.`date` <= cal.`date` 
) maxs 
group by cal_date 
) m2 
inner join example ex2 
on m2.mdate = ex2.`date` 
-- pick a reasonable end date for filtering.. 
where cal_date <= date('2015-06-15') 
order by cal_date 
; 

đầu ra

+------------------------+------------------------+---------+ 
|  cal_date  |   mdate   | status | 
+------------------------+------------------------+---------+ 
| June, 01 2015 00:00:00 | June, 01 2015 00:00:00 | Start | 
| June, 02 2015 00:00:00 | June, 01 2015 00:00:00 | Start | 
| June, 03 2015 00:00:00 | June, 03 2015 00:00:00 | Stage 2 | 
| June, 04 2015 00:00:00 | June, 03 2015 00:00:00 | Stage 2 | 
| June, 05 2015 00:00:00 | June, 03 2015 00:00:00 | Stage 2 | 
| June, 06 2015 00:00:00 | June, 03 2015 00:00:00 | Stage 2 | 
| June, 07 2015 00:00:00 | June, 07 2015 00:00:00 | Stage 3 | 
| June, 08 2015 00:00:00 | June, 07 2015 00:00:00 | Stage 3 | 
| June, 09 2015 00:00:00 | June, 07 2015 00:00:00 | Stage 3 | 
| June, 10 2015 00:00:00 | June, 07 2015 00:00:00 | Stage 3 | 
| June, 11 2015 00:00:00 | June, 07 2015 00:00:00 | Stage 3 | 
| June, 12 2015 00:00:00 | June, 07 2015 00:00:00 | Stage 3 | 
| June, 13 2015 00:00:00 | June, 07 2015 00:00:00 | Stage 3 | 
| June, 14 2015 00:00:00 | June, 07 2015 00:00:00 | Stage 3 | 
| June, 15 2015 00:00:00 | June, 07 2015 00:00:00 | Stage 3 | 
+------------------------+------------------------+---------+ 

sqlfiddle


tham khảo

+0

Cảm ơn, amdixon. Tôi sẽ quay lại khi tôi quay lại văn phòng. Trong khi chờ đợi, tôi sẽ làm việc để tìm hiểu ý nghĩa của nó :) Tôi chưa bao giờ sử dụng Cross Joins trước đây, và tự hỏi những gì họ đã được sử dụng cho. Tôi nghĩ tôi sắp tìm ra. –

+0

tham gia chéo có nghĩa là lấy tất cả các kết hợp của các bản ghi từ bộ dữ liệu trái và phải. vì vậy nếu bạn vượt qua tham gia tập dữ liệu với 2 bản ghi với tập dữ liệu có 5 bản ghi, bạn sẽ kết thúc với tập dữ liệu có 10 bản ghi. kiểm tra [tham gia chéo] (http://www.w3resource.com/sql/joins/cross-join.php). trong bối cảnh này, cách tạo chuỗi số – amdixon

+0

@RyanVincent có, bạn có thể sử dụng dữ liệu này như một nguồn dữ liệu sẵn có (để tạo chuỗi) cho dân số lịch. hiệu quả có lẽ không phải là một mối quan tâm, vì tải lịch sẽ chỉ xảy ra tối đa mỗi năm một lần. chỉ cần đảm bảo không có khoảng trống trong chuỗi id .. – amdixon

Các vấn đề liên quan