php-resource



Zurück   PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr > Entwicklung > SQL / Datenbanken
 

Login

 
eingeloggt bleiben
star Jetzt registrieren   star Passwort vergessen
 

 

 


SQL / Datenbanken Probleme mit SQL? Hier könnt ihr eure Fragen zu SQL (MySQL, PostgreSQL, MS-SQL und andere ANSI-SQL Server) los werden.

Antwort
 
LinkBack Themen-Optionen Thema bewerten
  #1 (permalink)  
Alt 20-11-2018, 16:56
frankwu
 Registrierter Benutzer
Links : Onlinestatus : frankwu ist offline
Registriert seit: Dec 2006
Beiträge: 5
frankwu ist zur Zeit noch ein unbeschriebenes Blatt
Standard letzter Datensatz aus Gruppe + vorletzter

Hallo,

ich habe eine Tabelle in der ich für mehrere Rechner (VMs) die Speicherplatzinfo speichere.

id,time,hostname,mountpoint,free,usage

nun frage ich die Tabelle ab und gruppiere nach hostname und mountpoint, und wende die Aggregat-funktion Max auf time an, um in jeder Gruppe den aktuellsten Wert abzufragen.

Code:
select max(created),hostname,mountpoint,free,`usage` from diskfree group by hostname,mountpoint
nun benötige ich aber zusätzlich den vorletzten Eintrag (Vergleichswert und für ein kommendes email-flag), wie stelle ich das am sinnvollsten an?
Ich dachte ich kann das in einem Subselect suchen (die id) und dann via left join reinlinken. Hat aber leider den nachteil, dass erst die komplette Tabelle in eine Temptable geschrieben wird (nicht gruppiert) und dann erst weiterverarbeitet wird...ein Performance-Supergau

Vielleicht habt ihr eine Idee

Gruß Frank

Geändert von frankwu (21-11-2018 um 16:59 Uhr)
Mit Zitat antworten
  #2 (permalink)  
Alt 20-11-2018, 18:38
h3ll
 Registrierter Benutzer
Links : Onlinestatus : h3ll ist offline
Registriert seit: Mar 2008
Beiträge: 3.604
h3ll befindet sich auf einem aufstrebenden Ast
Standard

Die Abfrage ist fehlerhaft. Im GROUP BY müssen alle Spalten aus dem SELECT angeführt werden.

Zu dem Thema gibts übrigens sogar einen Artikel im MySQL-Handbuch:

https://dev.mysql.com/doc/refman/8.0...group-row.html
Mit Zitat antworten
  #3 (permalink)  
Alt 20-11-2018, 18:54
frankwu
 Registrierter Benutzer
Links : Onlinestatus : frankwu ist offline
Registriert seit: Dec 2006
Beiträge: 5
frankwu ist zur Zeit noch ein unbeschriebenes Blatt
Standard

ich will doch nur nach den 2 Spalten (hostname+mountpoint) gruppieren und nicht nach allen...auslesen möchte ich aber alle. ein Gruppieren nach dem freien Speicherplatz (free) und der prozentualen Auslastung (usage) macht meiner Meinung nach nicht viel Sinn

dein Link zeigt (soweit ich die Queries verstehe) nur das Maximum aber nicht das vorletzte "Maximum". ersteres Habe ich mit dem "group by" ja schon erreicht...es zeigt mir pro hist und mountpoint den letzten Datensatz an (max(time)).
Mit Zitat antworten
  #4 (permalink)  
Alt 20-11-2018, 18:59
h3ll
 Registrierter Benutzer
Links : Onlinestatus : h3ll ist offline
Registriert seit: Mar 2008
Beiträge: 3.604
h3ll befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von frankwu Beitrag anzeigen
ich will doch nur nach den 2 Spalten (hostname+mountpoint) gruppieren und nicht nach allen...
Das geht nicht. Jede anständige Datenbank würde dir eine Fehlermeldung um die Ohren hauen. MySQL liefert halt stillheimlich ein zufälliges Ergebnis.

Zitat:
Zitat von frankwu Beitrag anzeigen
dein Link zeigt (soweit ich die Queries verstehe) nur das Maximum aber nicht das vorletzte "Maximum". ersteres Habe ich mit dem "group by" ja schon erreicht...es zeigt mir pro hist und mountpoint den letzten Datensatz an (max(time)).
Tut es nicht. Die Abfrage ist wie gesagt fehlerhaft. Wenn das Ergebnis stimmt, dann nur zufällig. MySQL würfelt einfach, welche Daten geliefert werden. Kann stimmen, oder auch nicht. In den meisten Fällen tut es das nicht.
Mit Zitat antworten
  #5 (permalink)  
Alt 21-11-2018, 16:11
frankwu
 Registrierter Benutzer
Links : Onlinestatus : frankwu ist offline
Registriert seit: Dec 2006
Beiträge: 5
frankwu ist zur Zeit noch ein unbeschriebenes Blatt
Standard

habe das Query jetzt entsprechend umgebaut auf den Weg aus der MySQL-Doku:

Code:
SELECT created,hostname,mountpoint,free,`usage`
FROM   diskfree d1
WHERE  created=(SELECT MAX(d2.created)
              FROM diskfree d2
              WHERE d1.hostname = d2.hostname AND d1.mountpoint=d2.mountpoint)
ORDER BY created;
dauert auch ewig, obwohl ich für created,hostname und mountpoint indizies definiert habe

explain sagt das:

Code:
"id"	"select_type"	"table"	"type"	"possible_keys"	"key"	"key_len"	"ref"	"rows"	"Extra"
"1"	"PRIMARY"	"d1"	"ALL"	\N	\N	\N	\N	"8712"	"Using where; Using filesort"
"2"	"DEPENDENT SUBQUERY"	"d2"	"ref"	"hostname,mountpoint"	"hostname"	"20"	"db.d1.hostname"	"2564"	"Using where"
tabellen-create sieht so aus:
Code:
CREATE TABLE `diskfree` (
	`id` INT(11) NOT NULL AUTO_INCREMENT,
	`created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
	`hostname` VARCHAR(6) NOT NULL COLLATE 'utf8_unicode_ci',
	`mountpoint` VARCHAR(15) NOT NULL COLLATE 'utf8_unicode_ci',
	`free` INT(11) NOT NULL COMMENT 'freier Speicher (Avail) in MB',
	`usage` INT(11) NOT NULL COMMENT 'belegt (Use) in %',
	PRIMARY KEY (`id`),
	INDEX `created` (`created`),
	INDEX `hostname` (`hostname`),
	INDEX `mountpoint` (`mountpoint`)
)
COLLATE='utf8_unicode_ci'
ENGINE=MyISAM
AUTO_INCREMENT=8707
;
bei der Join-variante sieht es genauso aus...

Code:
SELECT d1.created,d1.hostname,d1.mountpoint,d1.free,d1.`usage`
FROM diskfree d1
LEFT JOIN diskfree d2 ON d1.hostname = d2.hostname AND d1.mountpoint=d2.mountpoint AND d1.created < d2.created
WHERE d2.created IS NULL
ORDER BY d1.created;
Code:
"id"	"select_type"	"table"	"type"	"possible_keys"	"key"	"key_len"	"ref"	"rows"	"Extra"
"1"	"SIMPLE"	"d1"	"ALL"	\N	\N	\N	\N	"8724"	"Using filesort"
"1"	"SIMPLE"	"d2"	"ref"	"created,hostname,mountpoint"	"hostname"	"20"	"infoscreen.d1.hostname"	"2564"	"Using where; Not exists"
habe auch sowas probiert, funktioniert halt auch nicht, da das subquery zuerst aufgerufen wird und dort d1 noch nicht bekannt ist:
Code:
select distinct(concat_ws('_',d1.hostname,d1.mountpoint)) as host_mount,d1.hostname,d1.mountpoint from diskfree as d1
cross join 
  (select id from diskfree d3 where d3.hostname=d1.hostname and d3.mountpoint=d1.mountpoint order by d3.created limit 2) as d4
beim googlen bin ich auch auf das gestoßen: https://www.developerfiles.com/get-t...roup-in-mysql/

nur ich bekomme es nicht hin das auf meine Werte (und die 2-Spalten-Gruppe) umzusetzen

Geändert von frankwu (21-11-2018 um 17:41 Uhr) Grund: weiterer Versuch
Mit Zitat antworten
  #6 (permalink)  
Alt 21-11-2018, 18:45
frankwu
 Registrierter Benutzer
Links : Onlinestatus : frankwu ist offline
Registriert seit: Dec 2006
Beiträge: 5
frankwu ist zur Zeit noch ein unbeschriebenes Blatt
Standard

ich habe es jetzt so:

Code:
SELECT
  created,
  hostname,
  mountpoint,
  free,
  `usage`
FROM
  diskfree,
  (
    SELECT 
      GROUP_CONCAT(top_ids_per_group) AS top_ids
    FROM
      (
        SELECT 
          SUBSTRING_INDEX(GROUP_CONCAT(id ORDER BY created DESC), ',', 2) AS top_ids_per_group
        FROM
          diskfree
        GROUP BY
          hostname,mountpoint
      ) s_top_ids_per_group
  ) s_top_ids
WHERE
  FIND_IN_SET(id, top_ids)
ORDER BY
  hostname,
  mountpoint,
  created desc
;
ist ursprünglich von hier: SQL: selecting top N records per group, another solution | code.openark.org

Ergebnis scheint zu passen, aber auch hier habe ich beim group by andere Felder als beim zugehörigen Select (oder ist das sorum erlaubt?). Ich habe aber gelesen, dass diese Regel nur zutrifft, wenn man KEINE Aggregationsfunktion nutzt (in diesem Fall ist das group_concat(), vorher das max())

Abfrage geht auch sehr schnell

wäre nur besser, wenn letzter und vorletzte eintrag miteinander verjoint wären (eine zeile), vielleicht geht das noch

Geändert von frankwu (21-11-2018 um 19:04 Uhr)
Mit Zitat antworten
Antwort

Lesezeichen

Stichworte
group, mysql, vorletzter


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
[MySQL 4.1] Letzter Datensatz löschen SquallCW SQL / Datenbanken 6 29-01-2009 17:45
letzter datensatz dutt SQL / Datenbanken 17 28-04-2004 13:59
letzter COOKIE-Datensatz fehlt hardy245 PHP Developer Forum 4 27-10-2003 21:23
Letzter Datensatz mgoertz SQL / Datenbanken 11 25-07-2003 23:50
letzter Datensatz wird aus DB nicht gelesen TOlli2 PHP Developer Forum 11 21-02-2003 12:16

Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an


PHP News

Die RIGID-FLEX-Technologie
Die RIGID-FLEX-TechnologieDie sogenannte "Flexible Elektronik" , oftmals auch als "Flexible Schaltungen" bezeichnet, ist eine zeitgemäße Technologie zum Montieren von elektronischen Schaltungen.

06.12.2018 | Berni

ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlicht
ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlichtDie bekannte Marktplatzsoftware ebiz-trader ist in der Version 7.5.0 veröffentlicht worden.

28.05.2018 | Berni


 

Aktuelle PHP Scripte

HeidiSQL - kostenloses MySQL front-end Editor für Windows ansehen HeidiSQL - kostenloses MySQL front-end Editor für Windows

HeidiSQL - ist ein Windows-Editor für die bekannt open Source Datenbank mySQL

10.12.2018 Berni | Kategorie: MYSQL/ Management
piwik Open-Source Webanalyse-Software ansehen piwik Open-Source Webanalyse-Software

piwik ist eine gute Alternative zu Google Analytics. Viele Features und ein modernes Erscheinungsbild mit aussagefähigen Statistiken in Echtzeit

10.12.2018 phpler | Kategorie: PHP/ Besucherzaehler
jQuery Mobile ansehen jQuery Mobile

Touch-Optimized Web Framework für Smartphones & Tablets

09.12.2018 phpler | Kategorie: AJAX/ Framework
 Alle PHP Scripte anzeigen

Alle Zeitangaben in WEZ +2. Es ist jetzt 06:09 Uhr.