/ Forside / Teknologi / Udvikling / SQL / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
SQL
#NavnPoint
pmbruun 1704
niller 962
fehaar 730
Interkril.. 701
ellebye 510
pawel 510
rpje 405
pete 350
gibson 320
10  smorch 260
MySQL inline view med statiske data
Fra : Morten


Dato : 21-04-08 06:04

Hej, jeg har en applikation hvor brugeren vælger en dato range, fex.
2008-04-01 til 2008-04-03. Denne benyttes til at tælle antal events
der var "åbne" på den givne dato, altså for hver dato some_date findes
events hvor "some_date BETWEEN events.start_date AND events.end_date"

Udfordringen er, at få datoerne sendt til MySQL, her er en måde:

SELECT date_range.some_day, COUNT(*)
FROM events, (
SELECT DATE('2008-04-01') AS some_day FROM DUAL UNION ALL
SELECT DATE('2008-04-02') FROM DUAL UNION ALL
SELECT DATE('2008-04-03') FROM DUAL
) AS date_range
WHERE date_range.some_day BETWEEN events.start_date AND
events.end_date
GROUP BY 1

Er det den mest elegante måde? Altså, hvis der er 200 dage i den
initielle date range, så er det en pæn del UNION ALL's der skal til...
Nogen smartere måde? Jeg overvejer om jeg skal lave en stored
procedure som returnerer dagene givet start + slut, men vil helst
holde det i ren SQL om muligt...

Mvh.

Morten


 
 
Michael Zedeler (22-04-2008)
Kommentar
Fra : Michael Zedeler


Dato : 22-04-08 06:59

Morten wrote:
> Hej, jeg har en applikation hvor brugeren vælger en dato range, fex.
> 2008-04-01 til 2008-04-03. Denne benyttes til at tælle antal events
> der var "åbne" på den givne dato, altså for hver dato some_date findes
> events hvor "some_date BETWEEN events.start_date AND events.end_date"
>
> Udfordringen er, at få datoerne sendt til MySQL, her er en måde:
>
> SELECT date_range.some_day, COUNT(*)
> FROM events, (
> SELECT DATE('2008-04-01') AS some_day FROM DUAL UNION ALL
> SELECT DATE('2008-04-02') FROM DUAL UNION ALL
> SELECT DATE('2008-04-03') FROM DUAL
> ) AS date_range
> WHERE date_range.some_day BETWEEN events.start_date AND
> events.end_date
> GROUP BY 1

Hvorfor ikke bare noget i denne stil?

select count(*), date(events.start_date)
from events
where events.start_date between '2008-04-01' and '2008-04-03'
group by date(events.start_date)

Så kan du godt nok få huller med dage uden begivenheder, men dem må du
fylde op selv.

Mvh. Michael.

Kristian Damm Jensen (22-04-2008)
Kommentar
Fra : Kristian Damm Jensen


Dato : 22-04-08 14:23

Michael Zedeler wrote:
> Morten wrote:
>> Hej, jeg har en applikation hvor brugeren vælger en dato range, fex.
>> 2008-04-01 til 2008-04-03. Denne benyttes til at tælle antal events
>> der var "åbne" på den givne dato, altså for hver dato some_date
>> findes events hvor "some_date BETWEEN events.start_date AND
>> events.end_date" Udfordringen er, at få datoerne sendt til MySQL, her er
>> en måde:
>>
>> SELECT date_range.some_day, COUNT(*)
>> FROM events, (
>> SELECT DATE('2008-04-01') AS some_day FROM DUAL UNION ALL
>> SELECT DATE('2008-04-02') FROM DUAL UNION ALL
>> SELECT DATE('2008-04-03') FROM DUAL
>> ) AS date_range
>> WHERE date_range.some_day BETWEEN events.start_date AND
>> events.end_date
>> GROUP BY 1
>
> Hvorfor ikke bare noget i denne stil?
>
> select count(*), date(events.start_date)
> from events
> where events.start_date between '2008-04-01' and '2008-04-03'
> group by date(events.start_date)
>
> Så kan du godt nok få huller med dage uden begivenheder, men dem må du
> fylde op selv.

Hvilket i øvrigt er relativt nemt:

create table dates(date datetime not null);
insert into dates values('2008-01-01');
insert into dates values('2008-01-02');
insert into dates values('2008-01-03');
....

select date(d.date), isnull(events.start_date, 0; count(*))
from dates d
left join events
on d.date = events.start_date
and d.date between '2008-04-01' and '2008-04-03'
group by date(events.start_date)

Jeg er ikke inde i detaljerne i MySQL. Tanken med isnull her er at hvis
events.start_date er NULL returneres 0, ellers antallet af poster. Dette fif
er nødvendigt fordi det ellers ikke er muligt at skelne mellem en dato der
ikke modsvares af nogen forekomst i events og en der svarer til netop én
post i events.

--
Venlig hilsen /Best regards
Kristian Damm Jensen



Morten (22-04-2008)
Kommentar
Fra : Morten


Dato : 22-04-08 03:13

On Apr 22, 7:59 am, Michael Zedeler <mich...@zedeler.dk> wrote:
> Morten wrote:
> > Hej, jeg har en applikation hvor brugeren vælger en dato range, fex.
> > 2008-04-01 til 2008-04-03. Denne benyttes til at tælle antal events
> > der var "åbne" på den givne dato, altså for hver dato some_date findes
> > events hvor "some_date BETWEEN events.start_date AND events.end_date"
>
> > Udfordringen er, at få datoerne sendt til MySQL, her er en måde:
>
> > SELECT date_range.some_day, COUNT(*)
> > FROM events, (
> > SELECT DATE('2008-04-01') AS some_day FROM DUAL UNION ALL
> > SELECT DATE('2008-04-02') FROM DUAL UNION ALL
> > SELECT DATE('2008-04-03') FROM DUAL
> > ) AS date_range
> > WHERE date_range.some_day BETWEEN events.start_date AND
> > events.end_date
> > GROUP BY 1
>
> Hvorfor ikke bare noget i denne stil?
>
> select count(*), date(events.start_date)
> from events
> where events.start_date between '2008-04-01' and '2008-04-03'
> group by date(events.start_date)
>
> Så kan du godt nok få huller med dage uden begivenheder, men dem må du
> fylde op selv.

Hej Michael,

Det er altid rart med input fra dig så tak for det. Jeg har måske fået
tænkt mig selv op i en krog, men jeg er ikke helt sikker på at det du
skriver dækker.

Det der driver dato-intervallet, er brugerens input range, ikke event
start/stop. Så hvis en bruger søger i intervallet 2008-04-01 til
2008-04-03, og der er events med start_date 2008-03-31 og end_date
2008-04-02 så kommer de ikke med i din query så vidt jeg kan vurdere.

Mvh.

Morten

Michael Zedeler (22-04-2008)
Kommentar
Fra : Michael Zedeler


Dato : 22-04-08 16:04

Morten wrote:
> On Apr 22, 7:59 am, Michael Zedeler <mich...@zedeler.dk> wrote:
>> Morten wrote:
>>> Hej, jeg har en applikation hvor brugeren vælger en dato range, fex.
>>> 2008-04-01 til 2008-04-03. Denne benyttes til at tælle antal events
>>> der var "åbne" på den givne dato, altså for hver dato some_date findes
>>> events hvor "some_date BETWEEN events.start_date AND events.end_date"
>>> Udfordringen er, at få datoerne sendt til MySQL, her er en måde:
>>> SELECT date_range.some_day, COUNT(*)
>>> FROM events, (
>>> SELECT DATE('2008-04-01') AS some_day FROM DUAL UNION ALL
>>> SELECT DATE('2008-04-02') FROM DUAL UNION ALL
>>> SELECT DATE('2008-04-03') FROM DUAL
>>> ) AS date_range
>>> WHERE date_range.some_day BETWEEN events.start_date AND
>>> events.end_date
>>> GROUP BY 1
>> Hvorfor ikke bare noget i denne stil?
>>
>> select count(*), date(events.start_date)
>> from events
>> where events.start_date between '2008-04-01' and '2008-04-03'
>> group by date(events.start_date)
>>
>> Så kan du godt nok få huller med dage uden begivenheder, men dem må du
>> fylde op selv.
>
> Det er altid rart med input fra dig så tak for det. Jeg har måske fået
> tænkt mig selv op i en krog, men jeg er ikke helt sikker på at det du
> skriver dækker.
>
> Det der driver dato-intervallet, er brugerens input range, ikke event
> start/stop. Så hvis en bruger søger i intervallet 2008-04-01 til
> 2008-04-03, og der er events med start_date 2008-03-31 og end_date
> 2008-04-02 så kommer de ikke med i din query så vidt jeg kan vurdere.

Så du er interesseret i begivenheder der også ligger "hen over"
intervallet. I så fald kan du bare skrive sådan her:

SELECT *
FROM events
WHERE NOT (events.end < '2008-03-31' OR events.start > '2008-04-03)

Mvh. Michael.

N/A (22-04-2008)
Kommentar
Fra : N/A


Dato : 22-04-08 16:04



Morten (23-04-2008)
Kommentar
Fra : Morten


Dato : 23-04-08 06:47

On Apr 22, 5:03 pm, Michael Zedeler <mich...@zedeler.dk> wrote:
> Morten wrote:
> > On Apr 22, 7:59 am, Michael Zedeler <mich...@zedeler.dk> wrote:
> >> Morten wrote:
> >>> Hej, jeg har en applikation hvor brugeren vælger en dato range, fex.
> >>> 2008-04-01 til 2008-04-03. Denne benyttes til at tælle antal events
> >>> der var "åbne" på den givne dato, altså for hver dato some_date findes
> >>> events hvor "some_date BETWEEN events.start_date AND events.end_date"
> >>> Udfordringen er, at få datoerne sendt til MySQL, her er en måde:
> >>> SELECT date_range.some_day, COUNT(*)
> >>> FROM events, (
> >>> SELECT DATE('2008-04-01') AS some_day FROM DUAL UNION ALL
> >>> SELECT DATE('2008-04-02') FROM DUAL UNION ALL
> >>> SELECT DATE('2008-04-03') FROM DUAL
> >>> ) AS date_range
> >>> WHERE date_range.some_day BETWEEN events.start_date AND
> >>> events.end_date
> >>> GROUP BY 1
> >> Hvorfor ikke bare noget i denne stil?
>
> >> select count(*), date(events.start_date)
> >> from events
> >> where events.start_date between '2008-04-01' and '2008-04-03'
> >> group by date(events.start_date)
>
> >> Så kan du godt nok få huller med dage uden begivenheder, men dem må du
> >> fylde op selv.
>
> > Det er altid rart med input fra dig så tak for det. Jeg har måske fået
> > tænkt mig selv op i en krog, men jeg er ikke helt sikker på at det du
> > skriver dækker.
>
> > Det der driver dato-intervallet, er brugerens input range, ikke event
> > start/stop. Så hvis en bruger søger i intervallet 2008-04-01 til
> > 2008-04-03, og der er events med start_date 2008-03-31 og end_date
> > 2008-04-02 så kommer de ikke med i din query så vidt jeg kan vurdere..
>
> Så du er interesseret i begivenheder der også ligger "hen over"
> intervallet. I så fald kan du bare skrive sådan her:
>
> SELECT *
> FROM events
> WHERE NOT (events.end < '2008-03-31' OR events.start > '2008-04-03)
>
> Mvh. Michael.

Jeg forstår det ikke. Jeg kan godt se, at den query angiver hvilke
events der er åbne i intervallet, men hvordan man kommer derfra til at
se hvor mange der er åbne på de dato'er der ligger indenfor
brugerintervallet er det svære skridt. Jeg har dimest rundt med det
http://www.pastie.org/185411 - og jeg har været ude af ret mange
tangenter (self joins, subselects osv.) i et forsøg på at anvende
ovenstående query som fundament, men hidtil uden held.

Der kommer en update fra mig hvis jeg nogensinde finder en løsning.
Ellers er andre meget velkomne til at kaste et blik på ovenstående
pastie.

Mvh.

Morten

Morten (23-04-2008)
Kommentar
Fra : Morten


Dato : 23-04-08 07:51

> Der kommer en update fra mig hvis jeg nogensinde finder en løsning.
> Ellers er andre meget velkomne til at kaste et blik på ovenstående
> pastie.

En løsning der er ret fix er at benytter en integers table til at
generere en sekvens af dato'er:

http://expertanswercenter.techtarget.com/eac/knowledgebaseAnswer/0,295199,sid63_gci978319,00.html

Morten


Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408914
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste