Avatar billede hcthorsen Praktikant
20. november 2009 - 22:17 Der er 4 kommentarer og
3 løsninger

Grupper data efter "kvartal"

Jeg har brug for at kunne tælle op hvor mange gange et eller andet emne forekommer i min database i månederne 

februar-april
maj-juli
august-oktober
november-januar

Desværre kan jeg ikke bare bruge normale kvartaler. Søgningen skal altså tælle hvor mange gange et givent ord forekommer i en given kolonne over en periode på 3 måneder. Søgningen skulle også gerne kunne medtage årstallet med. Resultatet skulle komme ud

februar-april 2008: N=12
maj-juli 2008: N=0
august-oktober: N=23
november-januar: N=13
februar-april 2009: N=3
maj-juli 2009: N=27

Man må kunne bruge en eller anden kode til "kvartalsopgørelse" og modificere den lidt. Er der nogen der ligger inde med sådan noget?
20. november 2009 - 22:56 #1
Hvis der ikke er nogen der har en bedre loesning saa er det ikke uoverkommeligt at goere saadanne kvartalsoversigter "med haanden."  Jeg proevede at lave den foelgende mysql tabel og query hvilket gav det foelgende resultat.  (Jeg puttede vaerdier i tabellen lidt tilfaeldigt, tilfaeldigvis var der 2 'ord1' vaerdier hver tre maaneder.)

Her er tabellen:

ord  dato 
      ord1 2008-02-02
      ord2 2008-03-02
      ord1 2008-04-02
      ord1 2008-05-02
      ord1 2008-06-02
      ord2 2008-07-02
      ord1 2008-08-02
      ord1 2008-09-02
      ord2 2008-10-02
      ord2 2008-11-02
      ord1 2008-12-02
      ord1 2009-01-02
      ord3 2009-02-02
      ord1 2009-03-02
      ord1 2009-04-02
      ord1 2009-05-02
      ord1 2009-06-02
      ord4 2009-07-02
      ord5 2009-08-02
      ord1 2009-09-02
      ord1 2009-10-02
      ord3 2009-11-02

og mysql query:

SELECT 'february-april 2008', COUNT('ord1')
FROM hcthorsen1
WHERE dato BETWEEN '2008-02-01' AND '2008-04-31'
AND ord = 'ord1'
GROUP BY ord
UNION
SELECT 'may-july 2008', COUNT('ord1')
FROM hcthorsen1
WHERE dato BETWEEN '2008-05-01' AND '2008-07-31'
AND ord = 'ord1'
GROUP BY ord
UNION
SELECT 'august-october 2008', COUNT('ord1')
FROM hcthorsen1
WHERE dato BETWEEN '2008-08-01' AND '2008-10-31'
AND ord = 'ord1'
GROUP BY ord
UNION
SELECT 'november 2008-january 2009', COUNT('ord1')
FROM hcthorsen1
WHERE dato BETWEEN '2008-11-01' AND '2009-01-31'
AND ord = 'ord1'
GROUP BY ord
UNION
SELECT 'february-april 2009', COUNT('ord1')
FROM hcthorsen1
WHERE dato BETWEEN '2009-02-01' AND '2009-04-31'
AND ord = 'ord1'
GROUP BY ord
UNION
SELECT 'maj-juli 2009', COUNT('ord1')
FROM hcthorsen1
WHERE dato BETWEEN '2009-05-01' AND '2009-07-31'
AND ord = 'ord1'
GROUP BY ord

hvilket gav foelgende resultat:

february-april 2008 2
may-july 2008 2
august-october 2008 2
november 2008-january 2009 2
february-april 2009 2
maj-juli 2009 2
Avatar billede arne_v Ekspert
21. november 2009 - 01:19 #2
Det må kunne lade sig gøre hvis man fedter lidt med tiden.

Eksempel:

mysql> SELECT * FROM q;
+----+------------+
| id | t          |
+----+------------+
|  1 | 2008-02-01 |
|  2 | 2008-02-02 |
|  3 | 2008-02-03 |
|  4 | 2008-03-01 |
|  5 | 2008-04-01 |
|  6 | 2008-05-01 |
|  7 | 2008-05-01 |
|  8 | 2008-08-01 |
|  9 | 2008-12-01 |
| 10 | 2009-01-01 |
| 11 | 2009-08-01 |
| 12 | 2009-09-01 |
| 13 | 2009-10-01 |
| 14 | 2009-11-01 |
| 15 | 2009-12-01 |
| 16 | 2010-01-01 |
+----+------------+
16 rows in set (0.00 sec)

mysql>
mysql> SELECT ((YEAR(t)*12+MONTH(t)-2) DIV 3) DIV 4 AS starty,
    ->        (((YEAR(t)*12+MONTH(t)-2) DIV 3) MOD 4)*3+2 AS startm,
    ->        ((YEAR(t)*12+MONTH(t)-2) DIV 3 + 1) DIV 4 AS endy,
    ->        (((YEAR(t)*12+MONTH(t)-2) DIV 3 + 1) MOD 4)*3+1 AS endm,
    ->        COUNT(*) AS n
    -> FROM q
    -> GROUP BY (YEAR(t)*12+MONTH(t)-2) DIV 3;
+--------+--------+------+------+---+
| starty | startm | endy | endm | n |
+--------+--------+------+------+---+
|  2008 |      2 | 2008 |    4 | 5 |
|  2008 |      5 | 2008 |    7 | 2 |
|  2008 |      8 | 2008 |  10 | 1 |
|  2008 |    11 | 2009 |    1 | 2 |
|  2009 |      8 | 2009 |  10 | 3 |
|  2009 |    11 | 2010 |    1 | 3 |
+--------+--------+------+------+---+
6 rows in set (0.00 sec)
Avatar billede acore Ekspert
21. november 2009 - 01:36 #3
Der er 2 udfordringer i det:

Den første er at tælle ord. Det er let, med mindre et ord, der optræder flere gange i samme felt, skal tælles mere end en gang. Så jeg har tilladt mig at gå ud fra, at det ikke er tilfældet.

Den anden er det med kvartalerne. Det kan løses sådan her:

SELECT
  CONCAT(
    YEAR(dato),
    '-',
    CASE
      WHEN MONTH(dato) BETWEEN 2 AND 4 THEN 'feb-apr'
      WHEN MONTH(dato) BETWEEN 5 AND 7 THEN 'maj-jul'
      WHEN MONTH(dato) BETWEEN 8 AND 10 THEN 'aug-okt'
      ELSE 'nov-jan'
    END
  ) AS qtr,
  COUNT(dato) AS no
FROM min_tabel
WHERE LOCATE('et_bestemt_ord', tekst)
GROUP BY qtr
Avatar billede hcthorsen Praktikant
21. november 2009 - 16:56 #4
Jamen det er jo en lækker løsning, acore. Præcis det jeg skulle bruge. Nogen der har et problem med at jeg giver 30 point til arne_v og Christian_Belgien for ulejligheden og de resterende 140 til acore for den endelige løsning?
21. november 2009 - 17:28 #5
Fint med mig, jeg kan godt se at acore's loesning er smartere.
Avatar billede arne_v Ekspert
21. november 2009 - 17:39 #6
helt fint
Avatar billede acore Ekspert
21. november 2009 - 23:30 #7
Helt ok
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester