2015-12-31 12 views
5

मेरे पास परियोजनाओं का डेटा सेट है। परियोजनाएं शुरुआत से अंत तक स्थिति बदलती हैं, और किसी तालिका में स्थिति परिवर्तन की तारीख लॉग होती है (तालिका का नाम "ईवेंट" होता है - मेरी पसंद नहीं)। (सरलीकृत) इस प्रकार दिखाई देगा:MySQL किसी दिए गए स्थिति के लिए दो तिथियों के बीच अनुपलब्ध तिथियों को भरें

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

किसी विशेष दिनांक सीमा में (गतिशील निर्धारित किया जाना) मैं जो परियोजनाएं हैं जो स्थिति में हैं देखने के लिए सक्षम होना चाहता हूँ। हालांकि, डेटा के खिलाफ BETWEEN या अन्य क्वेरी का उपयोग केवल उन्हीं परियोजनाओं को खींच देगा जिनकी स्थिति उस अवधि के दौरान बदल दी गई है, जो अभी भी किसी दिए गए स्थिति पर नहीं हैं।

मैं वर्तमान में Excel में एक बहुत ही भद्दा समाधान बना लिया है जो स्थिति परिवर्तन तिथियों के बीच नई पंक्तियाँ, इसलिए की तरह में प्रतियां पंक्तियों:

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 

यह समाधान मुझ पर परियोजना के लिए स्थिति को क्वेरी करने की अनुमति देता है, कहते हैं कि , 2015-06-06 और देखें कि यह अभी भी चरण 2 पर है।

क्या कोई तरीका है कि मैं अपने डेटा को उसी डेटा को खींचने के लिए उपयोग कर सकता हूं, लेकिन एक क्वेरी के आउटपुट के रूप में? मैंने कैलेंडर तालिका का उपयोग करने के लिए कुछ सुझाव सुना है, लेकिन मुझे यकीन नहीं है कि यह कैसे काम करेगा। मैंने किसी को भी क्रॉस जॉइन की सलाह दी है, लेकिन फिर से, मैं विवरण से समझ नहीं पाया कि यह कैसे काम करेगा।

आपकी मदद के लिए अग्रिम धन्यवाद!

उत्तर

0

आपको सभी तिथियों के साथ एक टेबल बनाने की आवश्यकता नहीं है। आप अपनी स्थिति को प्रत्येक स्थिति के लिए प्रारंभ और समाप्ति तिथियां देने और एक कथन के बीच उपयोग करने के लिए बदल सकते हैं।

या अपने मौजूदा डेटा का उपयोग कर।

@datequery का उपयोग करके जिस तारीख को आप ढूंढना चाहते हैं।

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

आपके द्वारा पूछे जाने वाले दिनांक से पहले सबसे हालिया स्थिति में परिवर्तन लौटाता है।

@datequery = 2015-06-06 

Status 
Stage 2 
1

योजना

  • पार में शामिल होने के अंक और कैलेंडर की अवधि में date_add द्वारा कैलेंडर तालिका बनाने ..
  • तारीख < = कैलेंडर की तारीख के साथ कैलेंडर स्रोत के लिए अपने डेटा में शामिल होने
  • तारीख से अधिकतम ले < = कैलेंडर दिनांक
  • मूल डेटा स्रोत के लिए वापस में शामिल होने का दर्जा प्राप्त करने के लिए

सेटअप

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') 
; 

क्वेरी

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 
; 

उत्पादन

+------------------------+------------------------+---------+ 
|  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


संदर्भ

+0

धन्यवाद, amdixon। जब मैं कार्यालय में वापस आऊंगा तो मैं उसे एक शॉट दूंगा। इस बीच, मैं यह समझने पर काम करूंगा कि इसका क्या अर्थ है :) मैंने कभी भी क्रॉस का उपयोग कभी नहीं किया है, और आश्चर्य किया कि उनका क्या उपयोग किया गया था। मुझे लगता है कि मैं पता लगाने जा रहा हूँ। –

+0

क्रॉस जॉइन का मतलब बाएं और दाएं डेटासेट से रिकॉर्ड्स के सभी संयोजनों को लेना है। इसलिए यदि आप 5 रिकॉर्ड वाले डेटासेट के साथ 2 रिकॉर्ड वाले डेटासेट में शामिल हो जाते हैं, तो आप 10 रिकॉर्ड वाले डेटासेट के साथ समाप्त होते हैं। [क्रॉस जॉइन] देखें (http://www.w3resource.com/sql/joins/cross-join.php)। इस संदर्भ में यह एक संख्यात्मक अनुक्रम उत्पन्न करने का एक तरीका है – amdixon

+0

@RyanVincent हां आप इसे कैलेंडर आबादी के लिए आसानी से उपलब्ध डेटास्रोत (अनुक्रम पीढ़ी के लिए) के रूप में उपयोग कर सकते हैं। दक्षता शायद चिंता का विषय नहीं है, क्योंकि कैलेंडर लोड केवल वर्ष में अधिकतम एक बार होगा। बस सुनिश्चित करें कि आईडी अनुक्रम में कोई अंतराल नहीं है .. – amdixon

संबंधित मुद्दे