|
| SELECT i MySQL 3.23.52 Fra : Jesper Frank Nemholt |
Dato : 24-01-03 23:07 |
|
Hej!
Lige en SQL jeg ikke lige kan greje.
Jeg har følgende table (ligegyldige felter udeladt) :
mysql> desc process;
+----------------+-----------------------+------+-----+---------------------
+-------+
| Field | Type | Null | Key | Default
| Extra |
+----------------+-----------------------+------+-----+---------------------
+-------+
| timecode | datetime | | | 0000-00-00 00:00:00
| |
| systemid | smallint(5) unsigned | | MUL | 0
| |
| username | varchar(20) | | |
| |
| cpuusage | float(4,2) | YES | | NULL
| |
+----------------+-----------------------+------+-----+---------------------
+-------+
Jeg har en select der finder de 5 brugere der bruger mest CPU :
SELECT username, sum(cpuusage) AS sum_cpuusage FROM process WHERE systemid =
'2' AND timecode > now() - INTERVAL 1 DAY GROUP BY username ORDER BY
sum_cpuusage DESC LIMIT 5
Herefter vil jeg så gerne lave en select der for hver af disse brugere
lister deres CPU forbrug over tid. Dette bruger jeg så senere til at lave
grafer med.
For hvert timestamp kan samme bruger godt gå igen flere gange, da der
registeres per proces-basis, det er derfor jeg benytter mig af sum() og
group by.
Hvis jeg f.eks. siger at de 2 brugere der bruger mest CPU er bruger1 og
bruger2, så ville hver individuel select se således ud :
SELECT timecode,
sum(cpuusage) AS bruger1
FROM process
WHERE systemid = '2'
AND username = 'bruger1'
AND timecode > now() - INTERVAL 1 DAY
GROUP BY timecode
ORDER BY timecode
SELECT timecode,
sum(cpuusage) AS bruger2
FROM process
WHERE systemid = '2'
AND username = 'bruger2'
AND timecode > now() - INTERVAL 1 DAY
GROUP BY timecode
ORDER BY timecode
Nu ville jeg gerne have dem kombineret i een select så det kommer ud i
formatet "timecode, bruger1, bruger2".
Hvordan gøres dette ???
Jeg havde tænkt noget i stil med :
SELECT bruger1.timecode,
sum(bruger1.cpuusage) AS bruger1,
sum(bruger2.cpuusage) AS bruger2
FROM process AS bruger1,
process AS bruger2
WHERE bruger1.systemid = '2'
AND bruger1.username = 'bruger1'
AND bruger1.timecode > now() - INTERVAL 1 DAY
AND bruger2.systemid = '2'
AND bruger2.username = 'bruger2'
AND bruger2.timecode > now() - INTERVAL 1 DAY
GROUP BY bruger1.timecode
ORDER BY bruger1.timecode
Problemet er at det ikke giver de rette værdier, så et eller andet går galt.
Jeg formoder at det er min group by eller noget andet i den stil der er
forkert, men jeg ved ikke lige hvad.
Nogen der kan hjælpe ?
/Jesper
| |
Jesper Frank Nemholt (25-01-2003)
| Kommentar Fra : Jesper Frank Nemholt |
Dato : 25-01-03 18:53 |
|
"Jesper Frank Nemholt" <jfn@dassic.com> wrote in message
news:b0sdg3$2r9$1@sunsite.dk...
> Hej!
>
[clip]
Jeg svarer lige halvvejs på mit eget spørgsmål da jeg er kommet lidt videre.
Ønsket var at få nedenstående 2 selects samlet i een :
>
> SELECT timecode,
> sum(cpuusage) AS bruger1
> FROM process
> WHERE systemid = '2'
> AND username = 'bruger1'
> AND timecode > now() - INTERVAL 1 DAY
> GROUP BY timecode
> ORDER BY timecode
>
> SELECT timecode,
> sum(cpuusage) AS bruger2
> FROM process
> WHERE systemid = '2'
> AND username = 'bruger2'
> AND timecode > now() - INTERVAL 1 DAY
> GROUP BY timecode
> ORDER BY timecode
>
> Nu ville jeg gerne have dem kombineret i een select så det kommer ud i
> formatet "timecode, bruger1, bruger2".
Jeg formoder at det kan gøres v.h.a. en eller anden join, men hvordan ?
I en anden tabel gør jeg følgende (inner join) :
SELECT d1.timecode,
d1.readkb+d1.writekb AS dsk0,
d2.readkb+d2.writekb AS dsk1
FROM disk AS d1
INNER JOIN disk AS d2
ON d1.systemid = '2'
AND d1.name = 'dsk0'
AND d1.timecode > now() - INTERVAL 1 DAY
AND d2.systemid = '2'
AND d2.name = 'dsk1'
AND d2.timecode = d1.timecode
ORDER BY d1.timecode
Dette giver hvad jeg ønsker for disk devices, men så snart jeg laver dette i
forbindelse med sum() går det galt, d.v.s. der skal laves noget om for at
det virker med sum(cpuusage).
/Jesper
| |
Jesper Axelsen (27-01-2003)
| Kommentar Fra : Jesper Axelsen |
Dato : 27-01-03 19:30 |
|
Hej Jesper
Jeg forstår godt dit problem, men kan ikke lige komme på en måde
hvorpå du kan returnere det ønskede recordset.. Følgende sql kune dog
måske være en alternativ løsning. Som jeg kan se returnerer den de
samme data som dem du ønsker, bare på et andet format.
SELECT username, timecode,
sum(cpuusage) AS totalUsage
FROM process
WHERE systemid = 2
AND username in ( 'bruger1', 'bruger2' )
AND timecode > now() - INTERVAL 1 DAY
GROUP BY username, timecode
ORDER BY username, timecode
Håber det kan hjælpe - om ikke andet så måske give inspiration til din
videre søgen.
Mvh
Jesper
On Sat, 25 Jan 2003 18:52:33 +0100, "Jesper Frank Nemholt"
<jfn@dassic.com> wrote:
>"Jesper Frank Nemholt" <jfn@dassic.com> wrote in message
>news:b0sdg3$2r9$1@sunsite.dk...
>> Hej!
>>
>[clip]
>
>Jeg svarer lige halvvejs på mit eget spørgsmål da jeg er kommet lidt videre.
>Ønsket var at få nedenstående 2 selects samlet i een :
>
>>
>> SELECT timecode,
>> sum(cpuusage) AS bruger1
>> FROM process
>> WHERE systemid = '2'
>> AND username = 'bruger1'
>> AND timecode > now() - INTERVAL 1 DAY
>> GROUP BY timecode
>> ORDER BY timecode
>>
>> SELECT timecode,
>> sum(cpuusage) AS bruger2
>> FROM process
>> WHERE systemid = '2'
>> AND username = 'bruger2'
>> AND timecode > now() - INTERVAL 1 DAY
>> GROUP BY timecode
>> ORDER BY timecode
>>
>> Nu ville jeg gerne have dem kombineret i een select så det kommer ud i
>> formatet "timecode, bruger1, bruger2".
>
>Jeg formoder at det kan gøres v.h.a. en eller anden join, men hvordan ?
>
>I en anden tabel gør jeg følgende (inner join) :
>
>SELECT d1.timecode,
>d1.readkb+d1.writekb AS dsk0,
>d2.readkb+d2.writekb AS dsk1
>FROM disk AS d1
>INNER JOIN disk AS d2
>ON d1.systemid = '2'
>AND d1.name = 'dsk0'
>AND d1.timecode > now() - INTERVAL 1 DAY
>AND d2.systemid = '2'
>AND d2.name = 'dsk1'
>AND d2.timecode = d1.timecode
>ORDER BY d1.timecode
>
>
>Dette giver hvad jeg ønsker for disk devices, men så snart jeg laver dette i
>forbindelse med sum() går det galt, d.v.s. der skal laves noget om for at
>det virker med sum(cpuusage).
>
>/Jesper
>
| |
Jesper Frank Nemholt (27-01-2003)
| Kommentar Fra : Jesper Frank Nemholt |
Dato : 27-01-03 20:46 |
|
"Jesper Axelsen" <jesper@xelsen.dk> wrote in message
news:3mua3v4t2radcs52c6lbae1qgfisvje9ok@4ax.com...
> Hej Jesper
>
> Jeg forstår godt dit problem, men kan ikke lige komme på en måde
> hvorpå du kan returnere det ønskede recordset.. Følgende sql kune dog
> måske være en alternativ løsning. Som jeg kan se returnerer den de
> samme data som dem du ønsker, bare på et andet format.
>
> SELECT username, timecode,
> sum(cpuusage) AS totalUsage
> FROM process
> WHERE systemid = 2
> AND username in ( 'bruger1', 'bruger2' )
> AND timecode > now() - INTERVAL 1 DAY
> GROUP BY username, timecode
> ORDER BY username, timecode
>
> Håber det kan hjælpe - om ikke andet så måske give inspiration til din
> videre søgen.
Der var en på MySQL listen der rystede den rette SQL ud af ærmet. Det er i
samme stil som din, men med nogle IF statements tilføjet.
Jeg har testet den og den funger og er nu implementeret i PHP så den retter
brugernavnene til dynamisk :
SELECT timecode,
SUM(IF(username='bruger1',cpuusage,0)),
SUM(IF(username='bruger2',cpuusage,0))
FROM process
WHERE systemid = '2' AND
timecode > now() - INTERVAL 1 DAY AND
username in ('bruger1', 'bruger2')
GROUP BY timecode
ORDER BY timecode
Det fungerer i pricippet a la den left outer join jeg bruger til disk
statistics ved, korrekt til mit brug, at putte 0 ind de steder hvor der er
en timecode men hvor en bruger ikke har registeret CPU forbrug. Dette gør at
graferne ser korrekte ud.
Jeg ved ikke om jeg reelt også kunne bruge en left outer join, men de spæde
forsøg jeg gjorde gav ikke det rette sammen med sum().
/Jesper
| |
|
|