[SQL] Uniek aantal dagen tellen

Pagina: 1
Acties:
  • 328 views sinds 30-01-2008
  • Reageer

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Ik ben nu bezig met script om wat statistieken op mijn website te verzamelen. Ik wil onder andere weten op hoeveel unieke dagen er activiteit gemeten is op de site. Onderstaande kolom, "created" (type DATETIME) staat in een tabel met statistieken genaamd "stats":

code:
1
2
3
4
5
6
7
8
2002-10-04 22:56:45
2003-11-04 22:56:49
2004-11-04 22:56:51
2004-12-15 22:57:31
2004-12-17 23:21:04
2005-12-05 23:21:20
2005-12-05 23:21:23
2005-12-06 23:21:33

Ik probeer een query te verzinnen welke het unieke aantal dagen telt (6 in dit geval), maar heb moeite met een goede formulering. Volgens mij ben ik met onderstaande niet op de goede weg:

SQL:
1
SELECT COUNT(DISTINCT(DAYOFMONTH(created))) FROM stats

Wie kan mij in de goede richting wijzen?

[ Voor 5% gewijzigd door Reveller op 06-12-2005 20:01 ]

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
Je zult het datumtijd formaat moeten omzetten naar een datum formaat. Hoe dit precies moet is afhankelijk van de RDBMS. Voor MS SQL server kun je o.a. het volgende doen:

SQL:
1
select count(distinct (convert(varchar(10), datum,105) ) ) from ...

Oops! Google Chrome could not find www.rijks%20museum.nl


  • Gé Brander
  • Registratie: September 2001
  • Laatst online: 15-04 19:43

Gé Brander

MS SQL Server

Of met behulp van LEFT(dateofmonth, 10) alleen de datum selecteren. Of is dat 'duurder' in database land ten opzichte van de convert zoals P_de_B voorsteld.

[ Voor 61% gewijzigd door Gé Brander op 06-12-2005 20:11 ]

Vroeger was alles beter... Geniet dan maar van vandaag, morgen is alles nog slechter!


  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Ik gebruik overigens MySQL. Ik vraag mij af of bovenstaande manieren werken, omdat de dagen 1 t/m 31 in 12 verschillende maanden in meerdere jaren voorkomen...

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

Dan moet je alleen DAYOFMONTH en de equivalent voor dag gebruiken, toch?

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


  • Gé Brander
  • Registratie: September 2001
  • Laatst online: 15-04 19:43

Gé Brander

MS SQL Server

Reveller schreef op dinsdag 06 december 2005 @ 20:31:
Ik gebruik overigens MySQL. Ik vraag mij af of bovenstaande manieren werken, omdat de dagen 1 t/m 31 in 12 verschillende maanden in meerdere jaren voorkomen...
Ik ken MySQL niet, maar is er een LEFT functie? Dan is met elke eerste 10 karakters toch een unieke combinatie te maken? Dan heb je toch niets met 1-31, 1-12 te maken in verschillende jaren?

Vroeger was alles beter... Geniet dan maar van vandaag, morgen is alles nog slechter!


  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

Dan neem je ook jaar mee, en dat is niet de bedoeling.

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


  • Gé Brander
  • Registratie: September 2001
  • Laatst online: 15-04 19:43

Gé Brander

MS SQL Server

kenneth schreef op dinsdag 06 december 2005 @ 20:40:
Dan neem je ook jaar mee, en dat is niet de bedoeling.
hmm. Dat lees ik nergens, of ik begrijp het verkeerd.

Vroeger was alles beter... Geniet dan maar van vandaag, morgen is alles nog slechter!


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
kenneth schreef op dinsdag 06 december 2005 @ 20:40:
Dan neem je ook jaar mee, en dat is niet de bedoeling.
Volgens mij wel, hij wil gewoon unieke dagen.

In MySQL kun je dus de date functie gebruiken. DATE(een_datum_tijd) geeft alleen de datum, zonder de tijd.In combinatie met mijn eerste voorbeeld moet je er wel mee komen denk ik.

Oops! Google Chrome could not find www.rijks%20museum.nl


  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 21-04 09:31
LEFT weet ik niet in MySQL. Ik heb dit ook eens opgelost met SUBSTRING(created, 0, 10)

  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

Reveller schreef op dinsdag 06 december 2005 @ 20:31:
Ik gebruik overigens MySQL. Ik vraag mij af of bovenstaande manieren werken, omdat de dagen 1 t/m 31 in 12 verschillende maanden in meerdere jaren voorkomen...
Hieruit (en uit de testgegevens) trek ik de conclusie dat het jaar irrelevant is: 2003-11-04 en 2004-11-04 tellen als dezelfde dag.

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


  • Gé Brander
  • Registratie: September 2001
  • Laatst online: 15-04 19:43

Gé Brander

MS SQL Server

Kort door de bocht conclusie naar mijn mening, maar je kan het zo opvatten. Echter logisch vind ik het niet.
Een unieke dag is een unieke dag, en niet een dag die in meerdere jaren voorkomt.

[ Voor 28% gewijzigd door Gé Brander op 06-12-2005 20:47 ]

Vroeger was alles beter... Geniet dan maar van vandaag, morgen is alles nog slechter!


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
kenneth schreef op dinsdag 06 december 2005 @ 20:45:
[...]
Hieruit (en uit de testgegevens) trek ik de conclusie dat het jaar irrelevant is: 2003-11-04 en 2004-11-04 tellen als dezelfde dag.
Dat is volgens mij omdat hij twijfelt of DAYOFMONTH wel de goede functie is, maar dit blijft een beetje gokwerk;

@TS: 2004-12-05 en 2005-12-05, moet dat als 1 of als 2 geteld worden?

Oops! Google Chrome could not find www.rijks%20museum.nl


  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

Kijk naar de testset, en zijn aanname dat er zes uit moet komen ... dat kan alleen als je 4 november als 1 dag telt.

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
kenneth schreef op dinsdag 06 december 2005 @ 20:51:
Kijk naar de testset, en zijn aanname dat er zes uit moet komen ... dat kan alleen als je 4 november als 1 dag telt.
Je hebt gelijk, ik had niet gezien dat 4 november in zowel 2003 als 2004 in het voorbeeld stond

Oops! Google Chrome could not find www.rijks%20museum.nl


  • edeboeck
  • Registratie: Maart 2005
  • Laatst online: 18-04 07:52

edeboeck

mie noow noooothing ...

IMHO is deze code zowel de meest correcte (datumfunctie gebruiken voor datumfunctionaliteit, geen stringfunctie) als de meest performante (omdat je de functie gebruikt waarvoor hij gemaakt is).
SQL:
1
SELECT COUNT(DISTINCT(DATE_FORMAT(created,"%c-%e"))) AS [Aantal unieke dagen] FROM stats

Unieke dagen zijn unieke dagen, dus het jaar speelt wel degelijk een rol ... als TS enkel het huidige jaar wil, kan hij de query aanpassen als volgt (analoog voor jaar en/ofmaand):
SQL:
1
2
SELECT COUNT(DISTINCT(DATE_FORMAT(created,"%c-%e"))) AS [Aantal unieke dagen] FROM stats
WHERE YEAR(created)=intJaar

(intJaar is een integer variabele die het gewenste jaar bevat)

Meer info rond datum-/tijdfuncties: http://dev.mysql.com/doc/...e-and-time-functions.html

[ Voor 2% gewijzigd door edeboeck op 06-12-2005 21:09 . Reden: *oeps* nu pas testset [b]grondig[/b] bekeken |:( ]


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
edeboeck schreef op dinsdag 06 december 2005 @ 21:02:
IMHO is deze code zowel de meest correcte (datumfunctie gebruiken voor datumfunctionaliteit, geen stringfunctie) als de meest performante (omdat je de functie gebruikt waarvoor hij gemaakt is).
SQL:
1
SELECT COUNT(DISTINCT(DATE(created))) AS [Aantal unieke dagen] FROM stats

Unieke dagen zijn unieke dagen, dus het jaar speelt wel degelijk een rol ... als TS enkel het huidige jaar wil, kan hij de query aanpassen als volgt (analoog voor jaar en/ofmaand):
SQL:
1
2
SELECT COUNT(DISTINCT(DATE(created))) AS [Aantal unieke dagen] FROM stats
WHERE YEAR(created)=intJaar

(intJaar is een integer variabele die het gewenste jaar bevat)

Meer info rond datum-/tijdfuncties: http://dev.mysql.com/doc/...e-and-time-functions.html
Ik begreep het net als jij, en gaf date ook al als voorbeeld maar als je de opmerkingen van kenneth en de voorbeeld data bekijkt zie je dat dit niet is wat TS vraagt.

Oops! Google Chrome could not find www.rijks%20museum.nl


  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
P_de_B schreef op dinsdag 06 december 2005 @ 20:50:
[...]
@TS: 2004-12-05 en 2005-12-05, moet dat als 1 of als 2 geteld worden?
Misschien moet ik het beter uitleggen: ik wil in de tabel "stats" kijken van welke dagen in statistieken heb. Dat wil zeggen: als ik 35 records heb van de dag 5 december 2004, dan is 5 december 2004 een "unieke" dag. Als ik records heb staan met als datum 5 december 2005, dan is ook dat een "unieke" dag :)

De reden hiervoor is dat ik bijvoorbeeld een "gemiddeld aantal pageviews per dag" wil kunnen berekenen. Ik tel dan alle pageviews bij elkaar op, en deel deze door het aantal dagen waarvan ik statistieken. Vervolgens kun je staatjes weergeven als "vandaag 232 pageviews; dat is 12,5% boven het dagelijks gemiddelde over het afgelopen jaar".

[ Voor 60% gewijzigd door Reveller op 06-12-2005 21:08 ]

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
Ok, dan had ik toch gelijk ;)

Dit is een compleet voorbeeld: [rml]edeboeck in "[ SQL] Uniek aantal dagen tellen"[/rml]

Oops! Google Chrome could not find www.rijks%20museum.nl


  • edeboeck
  • Registratie: Maart 2005
  • Laatst online: 18-04 07:52

edeboeck

mie noow noooothing ...

*knip*

[ Voor 100% gewijzigd door edeboeck op 06-12-2005 21:15 . Reden: Overbodig door post P_de_B ]


  • Maxxi
  • Registratie: Mei 2004
  • Laatst online: 21-11-2025
$aantaldagen = 1;

mysql_query = SELECT * FROM stats;

while ($row blbabla){

if ($row[datum] != $temp){
$aantaldagen ++;
}
$temp = $row[datum];

[ Voor 16% gewijzigd door Maxxi op 06-12-2005 21:21 ]


  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Ontzettend bedankt, P_de_B en edeboeck, het werkt perfect. Ik ga nu wel de MySQL manual dieper bestuderen, want hier was ik zelf niet snel opgekomen _/-\o_

[ Voor 4% gewijzigd door Reveller op 07-12-2005 14:21 ]

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Verwijderd

_/-\o_ Heheh lekkere query inderdaad, zelfde als dat ik ooit heb gezien waar geen like werd gebruikt, maar alle gegevens opgehaald en met een regex worden gecontroleert :p
Pagina: 1