php.de

Zurück   php.de > Webentwicklung > Datenbanken

Datenbanken SQL und Co

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 30.10.2007, 09:09  
Moderator
 
Benutzerbild von cycap
 
Registriert seit: 13.02.2008
Beiträge: 6.816
PHP-Kenntnisse:
Fortgeschritten
cycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nett
Standard ORDER BY im Subquery

Hallo Leute,

ich stehe auch mal wieder vor einem Problem.

Die Grundlage:

Ich habe eine Tabelle in der Datensätze stehen mit deren aktuellen Status
Eine zweite "History"-Tabelle in der festgehalten wird wer wann den Status des Datensatzes auf was geändert hat.

Was bei rauskommen soll:

Ich möchte eine Abfrage machen in der ich den VORLETZTEN Status bekomme, aus Statistikgründen.

Idee / bisheriger Versuch:

Ich hatte die Idee ich könnte ja einen JOIN machen in dem ich das Subquery mit ORDER BY sortiere und mit LIMIT den zweiten Datensatz auslese.

Code:
 SELECT TM_calls. * , x.last
FROM TM_calls
LEFT JOIN (

SELECT TM_calls.id AS cid, TM_calls_stati_zo.status AS last
FROM TM_calls
LEFT JOIN TM_calls_stati_zo 
ON TM_calls.id = TM_calls_stati_zo.call
LIMIT 1 , 1
ORDER BY TM_calls_stati_zo.timestamp DESC

) AS x ON x.cid = TM_calls.id
TM_calls enthält also den vollständigen Datensatz und TM_calls_stati_zo die History aus der ich den zweitletzten Datensatz zur aktuellen ID brauche.

Das Problem:

Die Abfrage funktioniert (fast) denn lasse ich das ORDER BY weg bekomme ich keine MySQL-Fehlermeldung. Das Problem ist dann aber das ich nicht den vorletzten Status auslese sondern irgendeinen.

Die Fehlermeldung:

Sobald ich das ORDER BY so wie oben einfüge bekomme ich folgenden Fehler:

Zitat:
MySQL meldet:
#1250 - Table 'TM_calls_stati_zo' from one of the SELECTs cannot be used in global ORDER clause
Sonstiges:

Hoffe ihr habt ne Idee wie ich mein Vorhaben umsetzen kann.

Gruß,
Tim
cycap ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 30.10.2007, 10:30  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

Das Problem liegt wohl vielmehr am JOIN vermute ich.
So ganz hab ich noch kein DB-Schema vor Augen, kannst du kurz nochmal die Tabellen und ihre Spalten auflisten und erklären?
Zergling-new ist offline   Mit Zitat antworten
Alt 30.10.2007, 10:50  
Moderator
 
Benutzerbild von cycap
 
Registriert seit: 13.02.2008
Beiträge: 6.816
PHP-Kenntnisse:
Fortgeschritten
cycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nett
Standard

Ich vereinfache mal das ganze, gibt noch mehr Daten, aber die sind für diese Abfrage uninteressant.


TM_calls

Code:
id | name | status
1 | test1 | 5
2 | test2 | 4
3 | test2 | 5
(Der Status wäre hier theoretisch überflüssig, aber vereinfacht das ganze in anderen Abfragen)

TM_calls_stati_zo
Code:
id | call | status | timestamp 
1 | 1 | 4 | 20070428
2 | 1 | 5 | 20070501
3 | 2 | 4 | 20070502
4 | 3 | 2 | 20070503
5 | 3 | 3 | 20070504
6 | 3 | 5 | 20070505
Die Referenz ist also TM_calls.id 1 <-> n TM_calls_stati_zo.call

Nun hätt ich gerne für diese Beispiel bei Call 3 das Ergebnis 3, das wäre demnach der Status der als vorletztes gesetzt wurde. Bei Call 2 sollte das Ergebnis NULL sein, da vorher kein Status gesetzt wurde.
cycap ist offline   Mit Zitat antworten
Alt 30.10.2007, 11:56  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

Ich kann grad nicht so nachvollziehen warum du 2x LEFT JOIN benutzt, probiers mal so:
Code:
SELECT c.*, s.call AS lastState
FROM TM_calls AS c
LEFT JOIN (SELECT s.status FROM TM_calls_stati_zo AS s WHERE c.id = s.call ORDER BY s.timestamp DESC LIMIT 1, 1)
(wusste garnicht, dass man beim JOIN ein Sub-SELECT verwenden kann)

Wenn das mit dem gleichen Fehler abbricht, probiers mal mit VIEWs.
Zergling-new ist offline   Mit Zitat antworten
Alt 30.10.2007, 13:41  
Moderator
 
Benutzerbild von cycap
 
Registriert seit: 13.02.2008
Beiträge: 6.816
PHP-Kenntnisse:
Fortgeschritten
cycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nett
Standard

Zitat:
(wusste garnicht, dass man beim JOIN ein Sub-SELECT verwenden kann)
Kannste mal sehen, du kannst von mir auch noch was lernen
Den 2ten LEFT JOIN habe ich gemacht, weil ich mir gedacht habe das ich aus dem Subquery bestimmt nicht auf die Felder des Mainquerys zugreifen kann und ich hatte Recht.

Code:
SELECT c. * , temp.last AS lastState
FROM TM_calls AS c
LEFT JOIN (

SELECT s.call, s.status AS last
FROM TM_calls_stati_zo AS s
WHERE c.id = s.call
ORDER BY s.timestamp DESC
LIMIT 1 , 1
) AS temp ON c.id = temp.call
Zitat:
#1054 - Unknown column 'c.id' in 'where clause'
Wie mache ich das denn mit dem View?
cycap ist offline   Mit Zitat antworten
Alt 30.10.2007, 13:51  
Moderator
 
Benutzerbild von cycap
 
Registriert seit: 13.02.2008
Beiträge: 6.816
PHP-Kenntnisse:
Fortgeschritten
cycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nett
Standard

Zitat:
(wusste garnicht, dass man beim JOIN ein Sub-SELECT verwenden kann)
Das geht sogar in der FROM-Clause, warum dann nicht im JOIN?

Siehe hier:
http://www.phpfriend.de/forum/ftopic62960.html
cycap ist offline   Mit Zitat antworten
Alt 30.10.2007, 14:21  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

Hmm kniffliges Problem. Kann meinen Senf erst morgen dazu abgeben.
Zergling-new ist offline   Mit Zitat antworten
Alt 30.10.2007, 15:21  
Moderator
 
Benutzerbild von cycap
 
Registriert seit: 13.02.2008
Beiträge: 6.816
PHP-Kenntnisse:
Fortgeschritten
cycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nett
Standard

Ich hab mein Problem selbst gelöst, naja fast gelöst und jetzt erschreckt euch nicht

Code:
SELECT
	TM_calls.*,
	neu.last
FROM
	TM_calls
LEFT JOIN
	(
SELECT
	status AS last,
	`call`
FROM
	TM_calls_stati_zo AS orig
LEFT JOIN
	(
SELECT
	`call` AS cid,
	MAX(timestamp) AS ts
FROM
	TM_calls_stati_zo
GROUP BY
	`call`
ORDER BY
	`call`) AS temp
	ON
		orig.CALL = cid
ORDER BY
	orig.`call`,
	(timestamp = ts) ASC,
	timestamp DESC ) AS neu
	ON
		TM_calls.id = neu.`call`
GROUP BY
	`call`
Hab mir dabei mit meinem eigenen Posting hier im Forum geholfen

http://www.phpfriend.de/forum/ftopic62942.html

Das einzige was mir noch nicht gefällt ist das die Abfrage (logischerweise) nicht das o.g. NULL ausgibt wenn der aktuelle Status der erste Status ist, sondern den aktuellen Status selbst. Hat da jemand eine Idee?

Und könnte man die Abfrage sonst noch optimieren?
cycap ist offline   Mit Zitat antworten
Alt 30.10.2007, 15:49  
Moderator
 
Benutzerbild von cycap
 
Registriert seit: 13.02.2008
Beiträge: 6.816
PHP-Kenntnisse:
Fortgeschritten
cycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nett
Standard

Code:
SELECT
	TM_calls.*,
	IF(neu.last = status , NULL , neu.last) AS 'vorheriger Status' 
FROM
	TM_calls
LEFT JOIN
	(
SELECT
	status AS last,
	`call`
FROM
	TM_calls_stati_zo AS orig
LEFT JOIN
	(
SELECT
	`call` AS cid,
	MAX(timestamp) AS ts
FROM
	TM_calls_stati_zo
GROUP BY
	`call`
ORDER BY
	`call`) AS temp
	ON
		orig.CALL = cid
ORDER BY
	orig.`call`,
	(timestamp = ts) ASC,
	timestamp DESC ) AS neu
	ON
		TM_calls.id = neu.`call`
GROUP BY
	`call`
Ok jetzt hab ich das Problem mit dem NULL auch gelöst. Optimierungsvorschläge?
cycap ist offline   Mit Zitat antworten
Alt 30.10.2007, 16:45  
Moderator
 
Benutzerbild von cycap
 
Registriert seit: 13.02.2008
Beiträge: 6.816
PHP-Kenntnisse:
Fortgeschritten
cycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nett
Standard

Wer meint das war viel, dem sei gesagt das war nur wiederum ein Subquery

Fertig sieht das ganze so aus:

Code:
SELECT 
  DATE_FORMAT(FROM_UNIXTIME(TM_calls.timestamp),'%Y-%m-%d') AS eingetragen,
  TM_kunden.firma AS 'Firma',
  TM_kunden.stadt AS 'Stadt',
  TM_fehler.text AS 'Fehlerart',
  TM_calls.headline AS 'Überschrift',
  TM_calls.fehler AS 'Fehlerbeschreibung',
  TM_calls.loesung AS 'Lösung',
  TM_calls.prod AS 'bestellte Produkte',
  TM_calls_stati.text AS 'Status',
  IF(sub.zstat = TM_calls.status,NULL,sub.stat) AS 'vorheriger Status'
FROM TM_calls
LEFT JOIN TM_kunden ON TM_kunden.id = TM_calls.kunde
LEFT JOIN TM_fehler ON TM_fehler.id = TM_calls.fehlerart
LEFT JOIN TM_calls_stati ON TM_calls_stati.id = TM_calls.status
LEFT JOIN (
SELECT 
   TM_calls.id AS callid, 
   stati.text AS stat, 
   last AS zstat
FROM 
   TM_calls 
LEFT JOIN 
   ( 
SELECT 
   status AS last, 
   `call` 
FROM 
   TM_calls_stati_zo AS orig 
LEFT JOIN 
   ( 
SELECT 
   `call` AS cid, 
   MAX(timestamp) AS ts 
FROM 
   TM_calls_stati_zo 
GROUP BY 
   `call` 
ORDER BY 
   `call`) AS temp 
   ON 
      orig.CALL = cid 
ORDER BY 
   orig.`call`, 
   (timestamp = ts) ASC, 
   timestamp DESC ) AS neu 
   ON 
      TM_calls.id = neu.`call` 
LEFT JOIN `TM_calls_stati` AS stati ON neu.last = stati.id
GROUP BY 
   `call` 
) AS sub ON TM_calls.id = sub.callid
ORDER BY TM_calls.timestamp DESC
Die vielleicht längste SQL Abfrage der Welt ohne Where-Clause
cycap ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine 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
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Abfrage mit count, order by, group by...und Probleme BartTheDevil89 Datenbanken 2 15.06.2008 13:34
sql order by Joerg80 PHP Tipps 2008 17 28.03.2008 12:22
Abfrage = "SELECT * FROM links ORDER BY id" Taktaky PHP Tipps 2008 2 22.08.2007 14:37
order by rand() JEGO PHP Tipps 2007 25 28.04.2007 20:52
Problem mit Ausgabe bzw. Abfrage mit ORDER BY mayer Datenbanken 7 02.07.2006 21:45
[Erledigt] Order by Ausnahme Datenbanken 2 13.01.2006 13:31
order by erweiterung . frage zum verst�ndnis... Promaetheus Datenbanken 5 07.12.2005 14:26
UNION in einem Subquery Datenbanken 0 26.10.2005 13:24
[Erledigt] ORDER BY bei zusammengesetzten Abfragen Datenbanken 5 04.05.2005 09:39
SELECT tbl.col AS a ORDER BY tbl.a versionsabhängig? axo Datenbanken 3 15.04.2005 15:50
Syntaxfehler, wohin kommt ORDER BY PHP Tipps 2005 7 12.02.2005 13:21
[Erledigt] Select Statement mit exists subquery Datenbanken 5 09.12.2004 10:24
DISTINCT oder ORDER BY unknownsoul Datenbanken 5 20.08.2004 12:12
Sortieren mit ORDER BY Datenbanken 4 09.08.2004 09:23
Select mit Order By ... andrew22 Datenbanken 8 29.07.2004 12:55

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
order by subselect, subselect order by, php order left join, table \'ts\' from one of the selects cannot be used in global order clause, subselect max timestamp, order by in subselect, order by subquery, sql order by in unterabfrage, order by mit subselects arbeiten, php order by max, subselect mit order, sql query längster eintrag, group by subselect, längste sql abfrage, problem subquery order by, \from one of the selects cannot be used in global order clause\ union, from one of the selects cannot be used in global order clause, can not be used in global order clause, sql order by unterabfrage, sub select left join

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




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum

Creative Commons License
Dieser Inhalt ist unter einer Creative Commons-Lizenz lizenziert.