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 25-05-2010, 17:06
SoS
 Registrierter Benutzer
Links : Onlinestatus : SoS ist offline
Registriert seit: May 2010
Beiträge: 6
SoS befindet sich auf einem aufstrebenden Ast
Standard Mehrfache Ausgabe bei SQL-Abfrage aus 2 Tabellen

Hallo, ich hab eine Frage.
Ich habe zwei Tabellen:
fragen (ca 500 Einträge) und fragen_solved (ca 40.000 Einträge)

Meine Abfrage bisher lautete (Bsp.):
Code:
SELECT a.ID, a.Ersteller, a.Frage_QT, a.LVL_Code, a.erster, a.tester
FROM frage a
WHERE 
a.ID < 101 OR
a.erster LIKE 'NICK' OR
(a.Ersteller LIKE 'NICK' OR a.Ersteller LIKE 'NICK & %' OR a.Ersteller LIKE '% & NICK' OR a.Ersteller LIKE '% & NICK & %')
ORDER BY ID DESC
Nun will ich die Abfrage modifizieren, aber das haut irgendwie alles zusammen.
Ich würde die Abfrage gerne wiefolgt ändern:
Code:
WHERE (a.ID = b.LVL AND b.UID = 'NICK') OR
(a.`Ersteller` LIKE 'NICK' OR a.`Ersteller` LIKE 'NICK & %' OR a.`Ersteller` LIKE '% & NICK' OR a.`Ersteller` LIKE '% & NICK & %')
mit frage_solved as b..

Die Abfrage dauert ewig lang, und liefert ca 1.000.000+ Einträge, anstatt ca 150, was man aber mit SELECT INSTINCT abfangen kann, die Dauer der Abfrage jedoch nicht.

Nach probieren bin ich drauf gekommen, dass bei der ersten Abfrage, wenn ich FROM frage a, frage_solved b hinschreibe, ohne dass auf b eine Bedingung oder Ausgabe zutrifft, sich die Abfrage seehr verlängert, und die Ausgaben wieder mehrfach vorkommen und in die Millionen gehen.

Das zwingt natürlich meinen Server in die Knie und ist sicher nicht ideal, leider kann ich aber keinen Fehler entdecken, vor allem den Grund nicht, wieso sich dieselbe Abfrage (die 1.) so verlängert/ändert, wenn ich einfach eine Tabelle dazuschreibe, die zwar viele Einträge hat, aber nicht in die Abfrage weiters eingreift. Wäre toll, wenn mir wer helfen könnte,
danke

Geändert von SoS (25-05-2010 um 18:19 Uhr)
Mit Zitat antworten
  #2 (permalink)  
Alt 25-05-2010, 17:08
h3ll
 Registrierter Benutzer
Links : Onlinestatus : h3ll ist offline
Registriert seit: Mar 2008
Beiträge: 3.578
h3ll befindet sich auf einem aufstrebenden Ast
Standard

Bitte Code ordentlich und sauber formatieren. Niemand scrollt gern 2 Meter nach rechts.
Mit Zitat antworten
  #3 (permalink)  
Alt 25-05-2010, 17:16
SoS
 Registrierter Benutzer
Links : Onlinestatus : SoS ist offline
Registriert seit: May 2010
Beiträge: 6
SoS befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von h3ll Beitrag anzeigen
Bitte Code ordentlich und sauber formatieren. Niemand scrollt gern 2 Meter nach rechts.
sry, dachte code bricht auch um ^^ ist behoben
Mit Zitat antworten
  #4 (permalink)  
Alt 25-05-2010, 17:18
h3ll
 Registrierter Benutzer
Links : Onlinestatus : h3ll ist offline
Registriert seit: Mar 2008
Beiträge: 3.578
h3ll befindet sich auf einem aufstrebenden Ast
Standard

Mach einen sauberen INNER JOIN.

Die Theta-Style schreibweise ist schwer lesbar und verleitet zu Fehlern. Im blödesten Fall machst du einen Cross-Join und die Ergebnismenge vervielfacht sich.

Code:
SELECT      t1.foo, t2.bar
FROM        tabelle1 t1
INNER JOIN  tabelle2 t2 ON ( t2.id = t1.fremd_id )
WHERE       t1.foo > 1 AND t2.bar LIKE 'abc%'

Geändert von h3ll (25-05-2010 um 17:22 Uhr)
Mit Zitat antworten
  #5 (permalink)  
Alt 25-05-2010, 17:18
wahsaga
  Moderator
Links : Onlinestatus : wahsaga ist offline
Registriert seit: Sep 2001
Beiträge: 25.236
wahsaga befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von SoS Beitrag anzeigen
was man aber mit SELECT INSTINCT abfangen kann, die Dauer der Abfrage jedoch nicht.
Natürlich - die massive Anzahl an Datensätzen muss ja erst mal ermittelt werden, bevor überhaupt mit DISTINCT Duplikate rausgeworfen werden können.


Informiere dich über JOINs.
SELFHTML Artikel / Datenbanken
__________________
I don't believe in rebirth. Actually, I never did in my whole lives.
Mit Zitat antworten
  #6 (permalink)  
Alt 25-05-2010, 17:21
AmicaNoctis
  Moderatorin
Links : Onlinestatus : AmicaNoctis ist offline
Registriert seit: Jul 2009
Beiträge: 5.709
Blog-Einträge: 9
AmicaNoctis sorgt für eine eindrucksvolle AtmosphäreAmicaNoctis sorgt für eine eindrucksvolle Atmosphäre
Standard

Hallo,

kannst du mal bitte erläutern, was du eigentlich vor hast und die Felder den beiden Tabellen mit einer kurzen Erklärung auflisten? Die create-table-Statements könnten auch schon helfen.

Übrigens: Wenn du etwas mit LIKE vergleichst, ohne Platzhalter zu verwenden, solltest du lieber gleich = nehmen.

Gruß,

Amica
__________________
Hast du die Grundlagen zur Fehlersuche gelesen? Hast du Code-Tags benutzt?
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke!

Geändert von AmicaNoctis (25-05-2010 um 17:25 Uhr)
Mit Zitat antworten
  #7 (permalink)  
Alt 25-05-2010, 18:13
SoS
 Registrierter Benutzer
Links : Onlinestatus : SoS ist offline
Registriert seit: May 2010
Beiträge: 6
SoS befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von AmicaNoctis Beitrag anzeigen
Hallo,

kannst du mal bitte erläutern, was du eigentlich vor hast und die Felder den beiden Tabellen mit einer kurzen Erklärung auflisten?
Also, ich hatte bis jetz immer LVL_max gespeichert, und alle LVL darunter ausgegeben. Da die LVL nun aber nicht mehr der Reihe nach gemacht werden, muss ich für jedes LVL extra Speichern, ob USER das schon gelöst hat.
Dazu wird in frage_solved die User-ID in UID und das entsprechende LVL gespeichert.
Danach sollen die LVL abgefragt werden, die schon von USER gelöst wurden, also in frage_solved als UID|LVL vorkommen.
Zudem sollen noch die LVL angezeigt werden, die von ihm erstellt wurden.
Dies steht in frage unter "ersteller". Problem hier, er kann alleine oder zumehrt drinnen stehen, wo sie mit " & " getrennt sind. Ist er zumehr drinnen, kann er am Anfang stehen (USER & %), in der Mitte (% & USER & %) oder am Ende (% & USER). Wenn ihr hierführ eine bessere Abfrage wisst, bin ich gerne dafür offen
Die LVL sind in frage gespeichert und haben id als ID.

Ich hoffe, das ist halbwegs verständlich.
Ich probier nebenbei schon mit Joins rum jetz, danke
Mit Zitat antworten
  #8 (permalink)  
Alt 25-05-2010, 18:20
h3ll
 Registrierter Benutzer
Links : Onlinestatus : h3ll ist offline
Registriert seit: Mar 2008
Beiträge: 3.578
h3ll befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von SoS Beitrag anzeigen
Dies steht in frage unter "ersteller". Problem hier, er kann alleine oder zumehrt drinnen stehen, wo sie mit " & " getrennt sind. Ist er zumehr drinnen, kann er am Anfang stehen (USER & %), in der Mitte (% & USER & %) oder am Ende (% & USER).
Ein grober Fehler im Datenbankdesign. In einer Spalte sollte nicht mehr als eine Information stehen. Das macht das ganze natürlich unnötig kompliziert und performance-aufwändig.
Mit Zitat antworten
  #9 (permalink)  
Alt 25-05-2010, 19:09
SoS
 Registrierter Benutzer
Links : Onlinestatus : SoS ist offline
Registriert seit: May 2010
Beiträge: 6
SoS befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von h3ll Beitrag anzeigen
Ein grober Fehler im Datenbankdesign. In einer Spalte sollte nicht mehr als eine Information stehen. Das macht das ganze natürlich unnötig kompliziert und performance-aufwändig.
Das mag wohl sein, ist aber leider nicht mein Hauptproblem jetzt
Ich glaub langsam verstanden zu haben, wieso ich so viele Rückgaben bekomme.
Reduzieren wird den Code mal aufs wesentliche:
Code:
SELECT        *
FROM         frage a
INNER JOIN    frage_solved b ON (a.ID = b.LVL) 
WHERE        b.UID = '63' OR
        a.einsteller = 'SoS'
ORDER BY     ID DESC
So bekomm ich mal korrekterweise alle LVL, die User 63 gelöst hat.
Die 2. Bedingung jedoch wirft mir jedes LVL, das die Bedingung erfüllt, mehrfach raus, da das LVL ja für jeden User usw da steht, aufgrund des JOINS.
Kann man nicht irgendwie die beiden Abfragen getrennt voneinander machen, und das Ergebnis wieder zusammenfügen? Einzeln funktionieren die Abfragen nämlich wunderbar und ohne Auslastung.
Bsp: (Pseudocode)
Code:
SELECT        *
FROM         frage a
WHERE       a.einsteller = 'SoS'

AND

SELECT       a.*
FROM         frage a, frage_solved b
WHERE       b.UID='63' AND a.ID = b.LVL
Mit Zitat antworten
  #10 (permalink)  
Alt 25-05-2010, 19:18
AmicaNoctis
  Moderatorin
Links : Onlinestatus : AmicaNoctis ist offline
Registriert seit: Jul 2009
Beiträge: 5.709
Blog-Einträge: 9
AmicaNoctis sorgt für eine eindrucksvolle AtmosphäreAmicaNoctis sorgt für eine eindrucksvolle Atmosphäre
Standard

Zitat:
Zitat von SoS Beitrag anzeigen
Die 2. Bedingung jedoch wirft mir jedes LVL, das die Bedingung erfüllt, mehrfach raus, da das LVL ja für jeden User usw da steht, aufgrund des JOINS.
Nein, aufgrund des schlechten Designs, denn eigentlich könnte man das prima filtern bzw. gruppieren. Da du dich aber weigerst, das als Ursache anzuerkennen, wirst du mit der schlechten Performance leben müssen.
__________________
Hast du die Grundlagen zur Fehlersuche gelesen? Hast du Code-Tags benutzt?
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke!
Mit Zitat antworten
  #11 (permalink)  
Alt 25-05-2010, 19:54
SoS
 Registrierter Benutzer
Links : Onlinestatus : SoS ist offline
Registriert seit: May 2010
Beiträge: 6
SoS befindet sich auf einem aufstrebenden Ast
Standard

Im Code kommt die entsprechende Spalte doch garnicht mehr vor.
Dennoch aber die riesige Mehrfachausgabe jeder Zeile. Wie kann ich dem jetzt entgegen wirken?
Code:
SELECT        *
FROM         frage a
INNER JOIN    frage_solved b ON (a.ID = b.LVL) 
WHERE        b.UID = '63' OR
        a.einsteller = 'SoS'
ORDER BY     ID DESC

Geändert von SoS (25-05-2010 um 19:56 Uhr)
Mit Zitat antworten
  #12 (permalink)  
Alt 25-05-2010, 20:15
AmicaNoctis
  Moderatorin
Links : Onlinestatus : AmicaNoctis ist offline
Registriert seit: Jul 2009
Beiträge: 5.709
Blog-Einträge: 9
AmicaNoctis sorgt für eine eindrucksvolle AtmosphäreAmicaNoctis sorgt für eine eindrucksvolle Atmosphäre
Standard

GROUP BY …

Ansonsten musst du mal präziser werden und ein Beispiel wie es sein soll posten.
__________________
Hast du die Grundlagen zur Fehlersuche gelesen? Hast du Code-Tags benutzt?
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke!
Mit Zitat antworten
  #13 (permalink)  
Alt 25-05-2010, 20:32
SoS
 Registrierter Benutzer
Links : Onlinestatus : SoS ist offline
Registriert seit: May 2010
Beiträge: 6
SoS befindet sich auf einem aufstrebenden Ast
Standard

Code:
frage
ID    |    ...    |    Einsteller
1                Max
2                SoS
3                Tom
4                SoS
5                SoS

frage_solved
UID    |    LVL
63        1
63        2
63        3
50        1
50        2
50        3
50        4
50        5
Für den User SoS mit der ID 63 sollte nun 1,2,3 aus frage angezeigt werden, weil er diese gesolved hat, und 2,4,5 weil er diese eingestellt hat.

JOIN ich die beiden Tabellen, ergibt sich folgendes:

Code:
UID    |    LVL/ID    |    Einsteller
63        1        Max
63        2        SoS
63        3        Tom
50        1        Max
50        2        SoS
50        3        TOm
50        4        SoS
50        5        SoS

SELECT            *
FROM             frage a
INNER JOIN      frage_solved b ON (a.ID = b.LVL) 
WHERE            b.UID = '63' OR
            a.einsteller = 'SoS'
ORDER BY         ID DESC
Aufgrund von UID=63 wird 1,2,3 ausgegeben
Aufgrund von Einsteller = SoS wird 2,2,4,5 ausgegeben.
In diesem Bsp wird jetzt nur ein Wert zuviel ausgegeben, aber in der Praxis, ist es leider um vielfaches mehr. Ein reduzieren mittels DISTINCT liefert zwar das gewünschte Ergebnis, aber es wird leider zulange gebraucht dafür, da der Einsteller eines LVL bei jedem User gezählt wird..
Mach ich noch was falsch?

PS: Formatierung leider bissl doof...
Mit Zitat antworten
  #14 (permalink)  
Alt 25-05-2010, 20:39
AmicaNoctis
  Moderatorin
Links : Onlinestatus : AmicaNoctis ist offline
Registriert seit: Jul 2009
Beiträge: 5.709
Blog-Einträge: 9
AmicaNoctis sorgt für eine eindrucksvolle AtmosphäreAmicaNoctis sorgt für eine eindrucksvolle Atmosphäre
Standard

Sieh dir mal group by an (wie gesagt) und dazu noch group_concat.
__________________
Hast du die Grundlagen zur Fehlersuche gelesen? Hast du Code-Tags benutzt?
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke!
Mit Zitat antworten
Antwort

Lesezeichen


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

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
abfrage über 2 Tabellen, falsche Ausgabe.... bastian SQL / Datenbanken 4 14-07-2004 09:43
mehrfache elseif-Abfrage Citral666 PHP Developer Forum 5 27-02-2004 14:03
Abfrage 2er Tabellen aus 1 Datenbank / Ausgabe geht net Trexx PHP Developer Forum 17 16-02-2004 16:20
Abfrage aus mehren Tabellen und Ausgabe JamieWolf SQL / Datenbanken 2 20-01-2004 22:17
Mehrfache Abfrage manuelakersten SQL / Datenbanken 10 09-01-2003 13:53

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

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

Wissensbestand in Unternehmen
Wissensbestand in UnternehmenLebenslanges Lernen und Weiterbilden sichert Wissensbestand in Unternehmen

25.05.2018 | Berni


 

Aktuelle PHP Scripte

PHP Server Monitor

PHP Server Monitor ist ein Skript, das prüft, ob Ihre Websites und Server betriebsbereit sind.

11.09.2018 Berni | Kategorie: PHP/ Security
PHP WEB STATISTIK ansehen PHP WEB STATISTIK

Die PHP Web Statistik bietet Ihnen ein einfach zu konfigurierendes Script zur Aufzeichnung und grafischen und textuellen Auswertung der Besuchern Ihrer Webseite. Folgende zeitlichen Module sind verfügbar: Jahr, Monat, Tag, Wochentag, Stunde Folgende son

28.08.2018 phpwebstat | Kategorie: PHP/ Counter
Affilinator - Affilinet XML Produktlisten Skript

Die Affilinator Affilinet XML Edition ist ein vollautomatisches Skript zum einlesen und darstellen der Affili.net (Partnerprogramm Netzwerk) Produktlisten und Produktdaten. Im Grunde gibt der Webmaster seine Affilinet PartnerID ein und hat dann unmittelb

27.08.2018 freefrank@ | Kategorie: PHP/ Partnerprogramme
 Alle PHP Scripte anzeigen

Alle Zeitangaben in WEZ +2. Es ist jetzt 11:49 Uhr.