php.de

Zurück   php.de > Webentwicklung > PHP Einsteiger > PHP Tipps 2010

 
 
LinkBack Themen-Optionen Thema bewerten
Alt 28.01.2010, 13:10  
vci
Neuer Benutzer
 
Registriert seit: 28.01.2010
Beiträge: 6
PHP-Kenntnisse:
Anfänger
vci befindet sich auf einem aufstrebenden Ast
Standard result Variablen von SQL verbinden

Hallo zusammen,

ich sitze hier vor einem SQL-Problem und würde es gerne elegant lösen.
Es geht darum 3 Abfragen zu machen, und wenn jeweils eine Abfrage leer ist eine andere Abfrage zu machen. D.h. UNION funktioniert nicht, da man hier ja eben nicht leere Teilmengen abfangen kann (oder doch?)

Im Moment würde der Code dann so aussehen:
Abfrage 1 - IF-Teil-Abfrage 1
Ausgabe Abfrage
Abfrage 2 - IF-Teil-Abfrage 2
Ausgabe Abfrage
Abfrage 3 - IF-Teil-Abfrage 3
Ausgabe Abfrage

Wobei Ausgabe der Abfrage immer der gleiche Code ist. Das wird natürlich extrem unschön, wenn die Ausgabe der Abfrage 50 Zeilen sind

Was ich nun suche ist Folgendes:
Code:
// Abfrage 1
$sql = select ...
$result1 = mysql_query($sql, $db);
if (!$result) $sql = select andere Abfrage;
// Abfrage 2
$sql = select ...
$result2 = mysql_query($sql, $db);
if (!$result2) $sql = select andere Abfrage;
// Abfrage 3
$sql = select ...
$result3 = mysql_query($sql, $db);
if (!$result3) $sql = select andere Abfrage;
// Zusammenfuehren:
$result = $result1.$result2.$result3
// Ausgeben
while ($myrow = mysql_fetch_array($result) {
...
}
Leider funktioniert das so (natürlich) nicht. Gibt es irgendwie eine Append-Row-Funktion in PHP? Mit SQL-Mitteln laesst sich die Abfrage leider wirklich nicht hinbiegen!

Natuerlich ist die Anzahl und Bezeichnung der Felder gleich!

Ich habe das Problem noch auf mrunix.de gepostet und deshalb hier noch die Fortsetzung von dem Thema dort:
Also ich denke nicht, dass das Problem sich mit einer SQL-Abfrage erschlagen lässt. Das Problem ist eben nicht die Abfrage als solches zu Verknüpfen, sondern im "Fehlerfall" dann eine andere Abfrage zu machen.

Konkret soll es darum gehen, dass immer mehrere Werte eines Eintrages ausgegeben werden wenn der Eintrag > aktuelles Datum ist. Ist dieser Eintrag nicht vorhanden soll eine 2. Abfrage gemacht werden die den 1. Eintrag < aktuelles Datum zurückliefert.

Also eben:
select name,ort,adresse,mail from events where datum > curdate();
if empty: select name,ort,adresse,mail from events where datum < curdate();

Es handelt sich dabei um Veranstaltungen. So soll z.B.:
SchokoladenKonferenz Mai 2008
SchokoladenKonferenz Oktober 2009
SchokoladenKonferenz Juli 2010
SchokoladenKonferenz Juni 2011

Beispiele:
Sind wir im Juni 2008 soll die Konferenz von Oktober 2009 ausgegeben werden. Sind wir im Oktober 2011 und ein neuer Eintrag für 2012 existiert noch nicht, soll die Konferenz von 2011 ausgegeben werden (das wäre der Sonderfall, wenn die 1. Abfrage leer ist).

Dabei geht es nicht nur um SchokoladenKonferenz sondern zusätzlich noch um PralinenKonferenz und EisKonferenz. #Edit: Es sollen also immer *genau* die 3 "richtigen" Konferenzen ausgegeben werden und nicht mehr und nicht weniger

Wie soll das mit JOIN funktionieren?!
Bin total ratlos und zugegeben auch PHP/SQL Neuling
vci ist offline  
Sponsor Mitteilung
PHP Code Flüsterer

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

Alt 28.01.2010, 13:22  
Erfahrener Benutzer
 
Registriert seit: 21.12.2004
Beiträge: 5.240
PHP-Kenntnisse:
Fortgeschritten
mepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblick
mepeisen eine Nachricht über ICQ schicken mepeisen eine Nachricht über Skype™ schicken
Standard

Vielleicht Joins ind Verbindung mit COALESCE?

In etwa folgendes:
Code:
SELECT COALESCE(a.Spalte, b.Spalte) AS Spalte
FROM (SELECT * FROM TabelleA WHERE ....) AS a
FULL OUTER JOIN (SELECT * FROM TabelleB WHERE ...) AS b
ON ....
Die Funktion Coalesce gibt dir die erste Spalte zurück. Sollte diese Null sein, gibt sie dir die zweite Spalte zurück. Ist also das Ergebnis as A null, wird das Ergebnis aus B zurückgegeben.
So wäre es, wenn du genau einen Eintrag bräuchtest.

Dein Problem mit den "meheren Einträgen bei größer Datum" lässt sich so nur schwer abbilden, da SQL von der Logik her immer zeilweise arbeitet. Es gibt zwar Möglichkeiten (Subselects und Co), die lehne ich aber aus Performance-Gründen ab. SQL arbeitet dort nur zeilenweise. Für deinen Fall würde ich mit einem UNION arbeiten und einer Sortierung. Die neuesten Einträge immer nach oben sortieren.
Dazu in PHP ein kelines IF. Kommt ein Eintrag größer aktuelles Datum vor, setze ein Flag, so dass ein potentieller Eintrag kleiner aktuelles Datum im PHP übersprungen wird.
__________________
www.php-maven.org PHP und Maven vereint: Build/Deploy/Produktion/Konfiguration, Projekt Management, CI, PHPUnit, zahlreiche Frameworks
Twitter @ https://twitter.com/#!/mepeisen und Facebook @ http://t.co/DZnKSUih
mepeisen ist offline  
Alt 28.01.2010, 15:12  
Erfahrener Benutzer
 
Benutzerbild von Dark Guardian
 
Registriert seit: 10.10.2009
Beiträge: 2.637
PHP-Kenntnisse:
Fortgeschritten
Dark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekannt
Standard

Warum sollte UNION nicht funktionieren?

Code:
select name,ort,adresse,mail, '1' as query_num from events where datum > curdate()
UNION select name,ort,adresse,mail, '2' as query_num from events where datum < curdate()
UNION select name,ort,adresse,mail, '3' as query_num from events where datum = curdate()
ORDER BY query_num ASC;
Wenn der erste Select nichts zurückgibt hast du keine Einträge mit query_num = 1, ebenso bei den anderen. Dadurch kannst du die Ergebnisse, falls nötig, hinterher in PHP noch Unterscheiden. Bzw. du könntest die Einträge für 3 verschiedene Listenausgaben entsprechend sortieren:

PHP-Code:

$ausgabeNeuer 
'';
$ausgabeAelter '';
$ausgabeAktuell '';

$vars = array('ausgabeNeuer''ausgabeAelter','ausgabeAktuell');

while 
$row mysql_fetch_assoc($res)) {
   
$zurAusgabe $vars[$row['query_num']];
   $
$zurAusgabe .= 'Name: '.$row['name'].', Ort: '.$row['ort'].', Datum:'.$row['datum'].'<br/>';
}

echo 
'<b>Aktuelle Termine:</b>';
echo 
$ausgabeAktuell;
echo 
'<b>Vergangene Termine:</b>';
echo 
$ausgabeAelter;
echo 
'<b>Zukünftige Termine:</b>';
echo 
$ausgabeNeuer
__________________
"Alles im Universum funktioniert, wenn du nur weißt wie du es anwenden musst".

Geändert von Dark Guardian (28.01.2010 um 15:18 Uhr).
Dark Guardian ist offline  
Alt 28.01.2010, 15:15  
Erfahrener Benutzer
 
Registriert seit: 21.12.2004
Beiträge: 5.240
PHP-Kenntnisse:
Fortgeschritten
mepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblick
mepeisen eine Nachricht über ICQ schicken mepeisen eine Nachricht über Skype™ schicken
Standard

Genau das habe ich gemeint, Dark. Gut, ich meinte halt mit Sortierung und ohne query_num, kommt aber aufs gleiche raus. Union fuinktioniert schon, wenn du noch eine Nachbearbeitung im PHP machst. Der Autor wollte jedoch ohne eine Nachbearbeitung in PHP. Das geht zwar prinzipiell aber nur mit Subselects in der Where-Bedingung und das ist aus Performancesicht ebend nicht zu empfehlen.
__________________
www.php-maven.org PHP und Maven vereint: Build/Deploy/Produktion/Konfiguration, Projekt Management, CI, PHPUnit, zahlreiche Frameworks
Twitter @ https://twitter.com/#!/mepeisen und Facebook @ http://t.co/DZnKSUih
mepeisen ist offline  
Alt 28.01.2010, 15:31  
Erfahrener Benutzer
 
Benutzerbild von Dark Guardian
 
Registriert seit: 10.10.2009
Beiträge: 2.637
PHP-Kenntnisse:
Fortgeschritten
Dark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekannt
Standard

Zitat:
Zitat von mepeisen Beitrag anzeigen
Union fuinktioniert schon, wenn du noch eine Nachbearbeitung im PHP machst.
Wieso denn? Geht doch mit LIMIT 1 wenn er immer nur eine haben will.

Code:
select name,ort,adresse,mail, '1' as query_num from events where datum > curdate()
UNION select name,ort,adresse,mail, '2' as query_num from events where datum < curdate()
UNION select name,ort,adresse,mail, '3' as query_num from events where datum = curdate()
ORDER BY query_num ASC 
LIMIT 1;
Wenn der erste select nichts zurückliefert steht somit der Eintrag des zweiten Selects an erste Stelle und wird zurückgegeben. So kann der TE mit LIMIT 1 immer genau nach seiner Priorität (erst neu, dann alt, dann was auch immer) den aktuellen Konferenztermin ermitteln.

Ich hatte überlesen das er immer nur einen Termin haben wollte (erst den alten wenn kein neuer Existiert.) Das ist bei meienr Abfrage ja der Fall. Denn gibt der erste Query mit der Prüfung nach dem neuem Termin nichts zurück bekommt er durch LIMIT 1 das erste Ergebniss von Query 2.

Wenn er alle 3 haben will gibt er einfach jedem einzelnem Select ein LIMIT 1. Dann wird aber so oder so eine Nachbearbeitung in PHP fällig.

Man kann das query_num auch weglassen und nach Datum sortieren. Ich dachte halt bloß gerade bei der Ausgabe an etwas anderes...
__________________
"Alles im Universum funktioniert, wenn du nur weißt wie du es anwenden musst".

Geändert von Dark Guardian (28.01.2010 um 15:34 Uhr).
Dark Guardian ist offline  
Alt 28.01.2010, 15:58  
Erfahrener Benutzer
 
Registriert seit: 21.12.2004
Beiträge: 5.240
PHP-Kenntnisse:
Fortgeschritten
mepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblick
mepeisen eine Nachricht über ICQ schicken mepeisen eine Nachricht über Skype™ schicken
Standard

Nein. Er kriegt bei dir grundsätzlich nur einen. Er will aber aus dem ersten Teilselect (also wenn es neue Einträge hat) mehrere haben. So habe ichs ja verstanden. Das ist ja das Problem. Würde er in jedem Fall nur einen brauchen, wäre es ja einfach
__________________
www.php-maven.org PHP und Maven vereint: Build/Deploy/Produktion/Konfiguration, Projekt Management, CI, PHPUnit, zahlreiche Frameworks
Twitter @ https://twitter.com/#!/mepeisen und Facebook @ http://t.co/DZnKSUih
mepeisen ist offline  
Alt 28.01.2010, 16:24  
Erfahrener Benutzer
 
Benutzerbild von Dark Guardian
 
Registriert seit: 10.10.2009
Beiträge: 2.637
PHP-Kenntnisse:
Fortgeschritten
Dark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekannt
Standard

Zitat:
Zitat von mepeisen Beitrag anzeigen
Nein. Er kriegt bei dir grundsätzlich nur einen. Er will aber aus dem ersten Teilselect (also wenn es neue Einträge hat) mehrere haben. So habe ichs ja verstanden. Das ist ja das Problem. Würde er in jedem Fall nur einen brauchen, wäre es ja einfach
Der Gegenwärtige Query gibt nur für eine Konferenz das richtige Datum aus. Man könnte den Query jetzt theoretsich für jede Konferenz duplizieren, aber das ist wohl nicht im Sinne des TE.

Wenn das der Fall ist sieht die DB warscheinlich so aus:

Code:
konferenz | datum
eis       | 2010-11-01
kaffee    | 2009-01-01
eis       | 2009-04-01
schoki    | 2009-12-01
kaffee    | 2010-10-01
Der passen Query wäre also:

Code:
select name,ort,adresse,mail, '1' as query_num from events where datum > curdate()
UNION select name,ort,adresse,mail, '2' as query_num from events where datum < curdate()
UNION select name,ort,adresse,mail, '3' as query_num from events where datum = curdate()
ORDER BY query_num ASC, datum DESC GROUP BY konferenz;
Dann erhält er für jede Konferenz den passenden Eintrag. Wenn für 'eis' der erste Query trifft erhält er durch GROUP BY eben dieses Ergebniss. Wenn für 'schoki' der Query 2 und 3 treffen erhält er das Ergebniss aus Query 2 für 'schoki' und hat somit für jede Konferenz genau einen Treffer anhand der von ihm festgelegten Reihenfolge (neu, alt, whatever).

(ich weiss das ich group by da grad zweckentfremde ))
__________________
"Alles im Universum funktioniert, wenn du nur weißt wie du es anwenden musst".
Dark Guardian ist offline  
Alt 28.01.2010, 18:51  
vci
Neuer Benutzer
 
Registriert seit: 28.01.2010
Beiträge: 6
PHP-Kenntnisse:
Anfänger
vci befindet sich auf einem aufstrebenden Ast
Standard

vielen Dank schonmal fuer die guten Anregungen!

Also die Datenbank sieht so aus:
longname,shortname,ort, ..., category, ...

category ist dann z.B.:
Konferenz.Schoki
Konferenz.Praline
Konferenz.Eis

(ja, schlechtes Datenbankdesign - ist aber die Vorgabe!)

Ich habe mal die Abfrage ein wenig gekürzt, da es sonst zu unbersichtlich wird (Datumsformatierungssachen, etc):
Code:
$sql = "(SELECT longname,shortname,enddate FROM events where (category='Konferenz.Schoki' && enddate > CURDATE()) order by enddate ASC LIMIT 1) UNION (SELECT longname,shortname FROM events where (category='Konferenz.Praline' &&  enddate > CURDATE()) order by enddate ASC LIMIT 1) UNION (SELECT longname,shortname,enddate FROM events where (category='Konferenz.Eis' enddate > CURDATE()) order by enddate ASC LIMIT 1) order by startdate";
Das liefert mir eben nur die neusten Einträge (jeweils 1, in Summe also 3) - sofern vorhanden. Okay, das mit dem query_num muss ich mal ausprobieren, das gibt also die Position der Rückgabe an?
Okay, dann kann man natürlich über UNION die zusätzliche Methode < CURDATE() noch "vertüten"

Ich gehe das mal testen!

Edit:
Hm, also das mit dem '1' as query_num verstehe ich nicht und funktioniert auch nicht
Also um das noch einmal ganz deutlich zu sagen:
In Summe moechte ich immer 3 Ausgaben und zwar:
-1x Konferenz.Schoki
-1x Konferenz.Eis
-1x Konferenz.Praline
nicht mehr und nicht weniger, d.h. wenn es keinen "aktuellen" Eintrag gibt, dann soll eben der "aktuellste" alte Eintrag genommen werden!

Geändert von vci (28.01.2010 um 19:40 Uhr).
vci ist offline  
Alt 28.01.2010, 20:56  
Erfahrener Benutzer
 
Benutzerbild von Dark Guardian
 
Registriert seit: 10.10.2009
Beiträge: 2.637
PHP-Kenntnisse:
Fortgeschritten
Dark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekannt
Standard

Edit: Vergiss was ich geschrieben hab mit dem ganzem Union Müll. Dieser Query ist bei weitem besser:

Code:
SELECT category, MAX(date) AS date FROM `testcat` GROUP BY category
Zitat:
d.h. wenn es keinen "aktuellen" Eintrag gibt, dann soll eben der "aktuellste" alte Eintrag genommen werden!
MAX() gibt für jede Gruppe die GROUP BY erzeugt den höchsten Wert wieder.

Das heißt in deinem Falle das "aktuellste" Datum für jede Kategorie. Ob das nun in der Zukunft liegt oder nicht ist MySQL relativ egal. Sollte das relevant sein für die spätere Verarbeitung kannst du mit:

Code:
SELECT category, MAX(date) AS date, (MAX(date) > curdate()) AS is_future FROM `testcat` GROUP BY category
Dir noch eine extra Spalte ausgeben lassen ob das Datum in der Zukunft liegt.

(Habs im PMA getestet, sollte hinhauen... ))
__________________
"Alles im Universum funktioniert, wenn du nur weißt wie du es anwenden musst".

Geändert von Dark Guardian (28.01.2010 um 21:32 Uhr).
Dark Guardian ist offline  
Alt 28.01.2010, 21:31  
vci
Neuer Benutzer
 
Registriert seit: 28.01.2010
Beiträge: 6
PHP-Kenntnisse:
Anfänger
vci befindet sich auf einem aufstrebenden Ast
Standard

Vielen Dank für die Hilfe. Noch verstehe ich die Abfrage aber noch nicht

SELECT * <-- da sollen also die Spalten rein
FROM (SELECT * <-- da sollen also die Spalten rein
FROM testcat <-- Tabellenname: events
WHERE date > curdate() <-- hier fehlt also noch: && category='Konferenz.Schoki'
UNION SELECT * <-- da sollen also die Spalten rein
FROM testcat <-- Tabellenname: events
WHERE date < curdate()) <-- hier fehlt also noch: && category='Konferenz.Schoki'
AS current_events <-- ok?!
GROUP BY category <-- ok?!

Also wie gesagt:
Tabellenname: events
Spalten: longname,shortname,ort,...,category,...

Wobei category eben: Konferenz.Name


#### EDIT:
Okay, nach deinem Edit ist das hinfaellig

Hm der hoechste Wert ist ja auch nicht unbedingt der richtige, da ja manchmal auch Eintraege im Voraus erzeugt werden, also z.B.:
Konferenz.Schoki 2008
Konferenz.Schoki 2009
Konferenz.Schoki 2010 <-- wir sind da
Konferenz.Schoki 2011
Konferenz.Schoki 2012

Ich werde das trotzdem einmal probieren

Geändert von vci (28.01.2010 um 21:35 Uhr).
vci ist offline  
 


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
Variablen mit variablen verbinden??? DRT-Joe PHP Tipps 2009 13 22.05.2009 17:24
Klasse statt globaler Variablen ecomeback PHP-Fortgeschrittene 6 15.07.2008 16:30
Übergeben von Variablen an in PHP eingebundenes Perl-Script shredder01 PHP Tipps 2008 3 04.04.2008 09:25
Datei mit Variablen so includen, dass Variablen nutzbar? BartTheDevil89 PHP Tipps 2008 6 22.01.2008 20:57
unerklärliches Leeren von Variablen KuShi PHP Tipps 2007 2 08.07.2007 15:19
Teil einer Variablen mit einer Variablen ersetzen ? simsalabim PHP Tipps 2007 11 20.03.2007 20:36
Variable aus Variablen zusammensetzen juhuwoorps PHP Tipps 2007 1 28.11.2005 21:50
Suche Tipps für Persormance-Steigerung (Geld für Nützliches) Beitragsarchiv 18 16.08.2005 10:57
Variablen verbinden Jacks Rache PHP Tipps 2005-2 13 09.08.2005 12:32
$_GET Variablen weitergeben PHP Tipps 2005 3 01.03.2005 15:36
Variablen übergeben bzw. auslesen? PHP Tipps 2005 4 30.01.2005 03:56
[Erledigt] register globals off bei variablen Variablen... PHP Tipps 2005 4 25.01.2005 17:50
komplexe Variablen übergeben? PHP Tipps 2004-2 8 02.12.2004 08:29
Variablen per adresse übergeben rocco PHP Tipps 2004 7 24.07.2004 12:03

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
sql result, result sql, http://www.php.de/php-einsteiger/63896-result-variablen-von-sql-verbinden.html, variablen in sql, sql result ausgeben, php sql result ausgeben, php variablen in sql, sql $result, php variablen verbinden, php 2 variablen verbinden, sql variablen, 2 sql abfragen verbinden, php zwei variablen verknüpfen, sql results verbinden, $result sql, sql select verbinden, sql select spalten verbinden, sql select variable, php sql result, php sql limit

Alle Zeitangaben in WEZ +2. Es ist jetzt 21:00 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