/ 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: Leder efter bedre metode
Fra : Morten


Dato : 22-02-08 11:05


Hej, jeg har et setup hvor systemer kan registrere events i en tabel:

CREATE TABLE events (id INT AUTO_INCREMENT PRIMARY KEY, system_id INT,
value VARCHAR(32), created_at DATETIME);

INSERT INTO events (system_id, value, created_at) VALUES (5, 'hep',
'2008-02-10 16:00');
INSERT INTO events (system_id, value, created_at) VALUES (7, 'foo',
'2008-02-11 16:00');
INSERT INTO events (system_id, value, created_at) VALUES (9, 'hep',
'2008-02-11 16:00');
INSERT INTO events (system_id, value, created_at) VALUES (5, 'foo',
'2008-02-13 16:00');
INSERT INTO events (system_id, value, created_at) VALUES (10, 'foo',
'2008-02-14 16:00');
INSERT INTO events (system_id, value, created_at) VALUES (7, 'hep',
'2008-02-15 16:00');

Min problemstilling er at finde ud af, hvor mange systemer har value
'hep' til datoen D.

SELECT * FROM events outer_e
WHERE id = (SELECT MAX(id)
FROM events inner_e
WHERE outer_e.system_id = inner_e.system_id
AND value = 'hep'
AND DATE(inner_e.created_at) < DATE('2008-02-12'));

+----+-----------+-------+---------------------+
| id | system_id | value | created_at |
+----+-----------+-------+---------------------+
| 13 | 5 | hep | 2008-02-10 16:00:00 |
| 15 | 9 | hep | 2008-02-11 16:00:00 |
+----+-----------+-------+---------------------+

Det er som sådan fint nok, men det forekommer mig lidt kluntet. Er der
en smartere måde?

Morten


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


Dato : 22-02-08 11:15


>
> SELECT * FROM events outer_e
> WHERE id = (SELECT MAX(id)
> FROM events inner_e
> WHERE outer_e.system_id = inner_e.system_id
> AND value = 'hep'
> AND DATE(inner_e.created_at) < DATE('2008-02-12'));
>
> +----+-----------+-------+---------------------+
> | id | system_id | value | created_at |
> +----+-----------+-------+---------------------+
> | 13 | 5 | hep | 2008-02-10 16:00:00 |
> | 15 | 9 | hep | 2008-02-11 16:00:00 |
> +----+-----------+-------+---------------------+
>

Og så kommer bonus-spørgsmålet: Jeg vil allerhelst kunne trække
antallet af matchende records ud for hver dag i den seneste måned.
Den lette løsning er at lave COUNT(*) i den ydre select, og så lave en
union for hver date, men det må kunne gøres smartere?

SELECT '2008-02-12', COUNT(*) FROM events outer_e
WHERE id = (SELECT MAX(id)
FROM events inner_e
WHERE outer_e.system_id = inner_e.system_id
AND inner_e.value = 'hep'
AND DATE(inner_e.created_at) < DATE('2008-02-12'))
GROUP BY 1
UNION
SELECT '2008-02-13', COUNT(*) FROM events outer_e
WHERE id = (SELECT MAX(id)
FROM events inner_e
WHERE outer_e.system_id = inner_e.system_id
AND inner_e.value = 'hep'
AND DATE(inner_e.created_at) < DATE('2008-02-13'))
GROUP BY 1
...
...

Igen, det virker, men det er lige grimt nok. Hrmf..

Morten


Martin (23-02-2008)
Kommentar
Fra : Martin


Dato : 23-02-08 05:38

Morten wrote:
>> SELECT * FROM events outer_e
>> WHERE id = (SELECT MAX(id)
>> FROM events inner_e
>> WHERE outer_e.system_id = inner_e.system_id
>> AND value = 'hep'
>> AND DATE(inner_e.created_at) < DATE('2008-02-12'));
>>
>> +----+-----------+-------+---------------------+
>> | id | system_id | value | created_at |
>> +----+-----------+-------+---------------------+
>> | 13 | 5 | hep | 2008-02-10 16:00:00 |
>> | 15 | 9 | hep | 2008-02-11 16:00:00 |
>> +----+-----------+-------+---------------------+
>>
>
> Og så kommer bonus-spørgsmålet: Jeg vil allerhelst kunne trække
> antallet af matchende records ud for hver dag i den seneste måned.
> Den lette løsning er at lave COUNT(*) i den ydre select, og så lave en
> union for hver date, men det må kunne gøres smartere?

SELECT COUNT(*), created_at
FROM events
WHERE value = 'hep'
GROUP BY created_at

Martin (23-02-2008)
Kommentar
Fra : Martin


Dato : 23-02-08 05:36

Morten wrote:
> Hej, jeg har et setup hvor systemer kan registrere events i en tabel:
>
> CREATE TABLE events (id INT AUTO_INCREMENT PRIMARY KEY, system_id INT,
> value VARCHAR(32), created_at DATETIME);
>
> INSERT INTO events (system_id, value, created_at) VALUES (5, 'hep',
> '2008-02-10 16:00');
> INSERT INTO events (system_id, value, created_at) VALUES (7, 'foo',
> '2008-02-11 16:00');
> INSERT INTO events (system_id, value, created_at) VALUES (9, 'hep',
> '2008-02-11 16:00');
> INSERT INTO events (system_id, value, created_at) VALUES (5, 'foo',
> '2008-02-13 16:00');
> INSERT INTO events (system_id, value, created_at) VALUES (10, 'foo',
> '2008-02-14 16:00');
> INSERT INTO events (system_id, value, created_at) VALUES (7, 'hep',
> '2008-02-15 16:00');
>
> Min problemstilling er at finde ud af, hvor mange systemer har value
> 'hep' til datoen D.

SELECT COUNT(*)
FROM events
WHERE value = 'hep' AND created_at < DATE('2008-02-12')
GROUP BY system_id

>
> SELECT * FROM events outer_e
> WHERE id = (SELECT MAX(id)
> FROM events inner_e
> WHERE outer_e.system_id = inner_e.system_id
> AND value = 'hep'
> AND DATE(inner_e.created_at) < DATE('2008-02-12'));
>
> +----+-----------+-------+---------------------+
> | id | system_id | value | created_at |
> +----+-----------+-------+---------------------+
> | 13 | 5 | hep | 2008-02-10 16:00:00 |
> | 15 | 9 | hep | 2008-02-11 16:00:00 |
> +----+-----------+-------+---------------------+
>
> Det er som sådan fint nok, men det forekommer mig lidt kluntet. Er der
> en smartere måde?

Ved ikke lige hvad det er du vil med denne, for den passer godt nok ikke
til dit spørgsmål :)

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


Dato : 23-02-08 09:47

On Feb 23, 5:35 am, Martin <mar...@aarhof.invalid> wrote:
> Morten wrote:
> > Hej, jeg har et setup hvor systemer kan registrere events i en tabel:
>
> > CREATE TABLE events (id INT AUTO_INCREMENT PRIMARY KEY, system_id INT,
> > value VARCHAR(32), created_at DATETIME);
>
> > INSERT INTO events (system_id, value, created_at) VALUES (5, 'hep',
> > '2008-02-10 16:00');
> > INSERT INTO events (system_id, value, created_at) VALUES (7, 'foo',
> > '2008-02-11 16:00');
> > INSERT INTO events (system_id, value, created_at) VALUES (9, 'hep',
> > '2008-02-11 16:00');
> > INSERT INTO events (system_id, value, created_at) VALUES (5, 'foo',
> > '2008-02-13 16:00');
> > INSERT INTO events (system_id, value, created_at) VALUES (10, 'foo',
> > '2008-02-14 16:00');
> > INSERT INTO events (system_id, value, created_at) VALUES (7, 'hep',
> > '2008-02-15 16:00');
>
> > Min problemstilling er at finde ud af, hvor mange systemer har value
> > 'hep' til datoen D.
>
> SELECT COUNT(*)
> FROM events
> WHERE value = 'hep' AND created_at < DATE('2008-02-12')
> GROUP BY system_id
>
>
>
>
>
> > SELECT * FROM events outer_e
> > WHERE id = (SELECT MAX(id)
> > FROM events inner_e
> > WHERE outer_e.system_id = inner_e.system_id
> > AND value = 'hep'
> > AND DATE(inner_e.created_at) < DATE('2008-02-12'));
>
> > +----+-----------+-------+---------------------+
> > | id | system_id | value | created_at |
> > +----+-----------+-------+---------------------+
> > | 13 | 5 | hep | 2008-02-10 16:00:00 |
> > | 15 | 9 | hep | 2008-02-11 16:00:00 |
> > +----+-----------+-------+---------------------+
>
> > Det er som sådan fint nok, men det forekommer mig lidt kluntet. Er der
> > en smartere måde?
>
> Ved ikke lige hvad det er du vil med denne, for den passer godt nok ikke
> til dit spørgsmål :)

Det er lidt mere tricky end du antager Det jeg gerne vil vide er,
hvor mange systemer har value 'hep' til tiden T. Din query returnerer
jo også records for systemer der ikke længere har value 'hep':

mysql> SELECT * FROM events WHERE value = 'hep' AND created_at <
DATE('2008-02-16') GROUP BY system_id;
+----+-----------+-------+---------------------+
| id | system_id | value | created_at |
+----+-----------+-------+---------------------+
| 13 | 5 | hep | 2008-02-10 16:00:00 |
| 18 | 7 | hep | 2008-02-15 16:00:00 |
| 15 | 9 | hep | 2008-02-11 16:00:00 |
+----+-----------+-------+---------------------+
3 rows in set (0,00 sec)

System 5 har value 'foo' til tiden 2008-02-16, så udfordringen
består

Morten

Søg
Reklame
Statistik
Spørgsmål : 177428
Tips : 31962
Nyheder : 719565
Indlæg : 6407944
Brugere : 218877

Månedens bedste
Årets bedste
Sidste års bedste