Eindämmung von SQL-Abfrage-Werten

  • Themenstarter Themenstarter Patrik Garten
  • Beginndatum Beginndatum
Oh, eine Fehlermeldung! Das ist doch schon mal was. Du musst wissen, Fehlermeldungen sind meistens dazu da, dass man sie lesen kann und sie einem Hinweise auf mögliche Fehler geben! Ja wirklich, darum heissen sie Fehlermeldungen!

Und wenn man noch weiss, wie der Code zur Zeit der Fehlermeldung genau ausgesehen hat, dann hat man ev. schon die halbe Lösung in der Hand.

Glaub mir, Fehlermeldungen sind kein Abfall, dass sind deine Freunde bei Problembehebungen!
 
Oh, eine Fehlermeldung! Das ist doch schon mal was. Du musst wissen, Fehlermeldungen sind meistens dazu da, dass man sie lesen kann und sie einem Hinweise auf mögliche Fehler geben! Ja wirklich, darum heissen sie Fehlermeldungen!

Danke, verarschen kann ich mich auch selber, dazu brauche ich dich nicht! ;-)

Also würde ich dich dann doch bitten höfflich zu bleiben, ich meine ich habe dich nicht Angegriffen oder sonstwas. Außerdem ist es mir selbst auch bewusst! Allerdings bringt mich die Fehlermeldung auch nicht weiter. Sonst würde ich hier ja schließlich nicht reinposten! ;-D

Aber könntest du mir vielleicht bitte einmal sagen, wie ich den aktuellsten Eintrag - sagen wir mal ich habe eine Tabelle mit drei Einträgen von ein und der selben Person die eben dreimal umgezogen ist, allerdings brauche ich nur den obersten Eintrag, weil das der aktuellste Wohnort ist, weiß ich anhand dem eingetragenen Datum. - ausgeben kann? Ich habe die Einträge schon mit einem ORDER BY ... DESC sotiert, aber es fehlt einfach jetzt nur noch das mit dem das er mir wirklich nur den aktuellsten Eintrag von der Person ausgibt.
 
Sorry, aber es fällt mir sehr schwer höflich zu bleiben wenn ich Rückfragen habe und nie eine Antwort darauf bekomme. Und wenn dann wiedersprechen sie sich.

Einmal schreibst du, dass du das gleiche Resultat wie am anfang bekommst, das ander mal schreibst du dass du Fehlermeldungen kriegst.

Aber du schreibst nirgens was die Fehlermeldung sagt, auch nicht mit welchem Code die Fehlermeldung entstand.

Wie soll ich dir da helfen?

Auf deine Frage steht die Antwort in meinem ersten Posting im Thread
.
Das MAX() auf das Datum nehmen, welches du mit einem GROUP BY auf die Person ermittelst.
Dieses Resultat wieder mit der Tabelle verbinden (INNER JOIN) wobei die Personen-ID mit sich selbst und das max_datum mit dem datum verglichen wird.
 
Sorry, aber es fällt mir sehr schwer höflich zu bleiben wenn ich Rückfragen habe und nie eine Antwort darauf bekomme. Und wenn dann wiedersprechen sie sich.

Dann sollte man das woll lernen. Geduld ist etwas was der Mensch braucht! Ganz besonders bei einem der neu in einer Sache dabei ist. ;-D

Einmal schreibst du, dass du das gleiche Resultat wie am anfang bekommst, das ander mal schreibst du dass du Fehlermeldungen kriegst.

Ja, entweder ich bekomme keine Resultat oder er gibt mir Fehlermeldungen like this aus:
Dynamic SQL Error SQL error code = -204 Ambiguous field name between table VERSICHERTENSTATUS and derived table SELECT_DATE VS_PAT_NR
Allerdings ist das nur ein Beispiel.

Das MAX() auf das Datum nehmen,
Wofür soll das gut sein? Um ein Datum zu sotieren kann man doch
SQL:
ORDER BY
                            vs_ab_datum DESC;
genauso gut hernehmen!?

welches du mit einem GROUP BY auf die Person ermittelst.
Dieses Resultat wieder mit der Tabelle verbinden (INNER JOIN) wobei die Personen-ID mit sich selbst und das max_datum mit dem datum verglichen wird.
Das hört sich einleuchtend an. ^.^

Ich schau mal was ich machen kann, dankeschön.
 
Zuletzt bearbeitet von einem Moderator:
Also die Fehlermeldung sagt aus, dass du ein Feld aus einer Tabelle im SQL hast, dass mit demselben Namen in mindestens 2 Quellen vorkommt. Dadurch weiss SQL nicht, welches der 2 Felder es nehmen soll.
Darum sollte man bei komplexeren SQLs immer den Tabelennamen ode ggf den Tabelen-Alias vor das Feld setzen.
Also versichertenstatus.vs_pat_nr anstelle von nur vs_pat_nr.
Somit weiss dann mySQL, elches der Felder du da verwenden willst.

MAX() anstele von ORDER BY
Nun, MAX() ist eine Gruppierungs-Funktion. Will heissen, dass er den höchsten Wert innerhalb einer Gruppierung nimmt. ORDER BY sortiert einfach alle Einträge. Somit hast du nachher noch immer die gleiche Anzahl Einträge wie vorher. Das ist nicht das was wir brauchen.
Teste einfach mal mit phpMyAdmin das Subquery und schau dir das Resultat an. Dann wirst du schon erkennen, warum MAX() und GROUP BY nicht dasselbe ist
SQL:
        SELECT
            vs_pat_nr,
            MAX(vs_ab_datum) AS max_vs_ab_datum
        FROM
            versichertenstatus
        WHERE
            LOWER(vs_pat_nr) LIKE '{$text}%'
        GROUP BY
            vs_pat_nr

Nachtrag:
Hättest du die Güte doch mal dein aktuelles Test-SQL, welches diesen Fehler generiert, hier zu posten könnt ich dir genauer sagen wo du den Tabellennamen vor das Feld setzen müsstest. Aber das fordere ich ja bereits seit eingen Posts vergebens....
 
Zuletzt bearbeitet von einem Moderator:
Also die Fehlermeldung sagt aus, dass du ein Feld aus einer Tabelle im SQL hast, dass mit demselben Namen in mindestens 2 Quellen vorkommt. Dadurch weiss SQL nicht, welches der 2 Felder es nehmen soll.
Darum sollte man bei komplexeren SQLs immer den Tabelennamen ode ggf den Tabelen-Alias vor das Feld setzen.
Also versichertenstatus.vs_pat_nr anstelle von nur vs_pat_nr.

Ah, ok, das ist schon mal gut zu wissen.

Somit weiss dann mySQL, elches der Felder du da verwenden willst.
Allerdings arbeite ich nicht mit MySQL, sondern mit FireBird.. :-/

Und was auch bei mir passiert wenn ich versuche ein GROUP BY in meinen Code mit einzubauen:
Dynamic SQL Error SQL error code = -104 Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause)
 
Ich habe mein Problem jetzt so halbwegs gelöst. Ich habe zwar noch ein paar Leute doppelt oder dreifach, ... aber den größten Teil habe ich jetzt schon weg geschafft und zwar mit der SQL-Abfrage:

SQL:
$query = "SELECT
                        pa_name,
                        pa_vorname,
                        pa_titel,
                        substring(100+extract(DAY FROM pa_geb_datum)from 2 for 2)||
                            '.'|| substring(100+extract(MONTH FROM pa_geb_datum)from 2 for 2)||
                            '.'|| extract(YEAR FROM pa_geb_datum),
                        vs_kas_bezeichnung,
                        vs_versich_art,
                        vs_mart,
                        pa_behandler,
                        pa_pat_nr,
                        vs_ab_datum
                     FROM
                        patient,
                        versichertenstatus
                    WHERE
                        pa_pat_nr=vs_pat_nr
                        AND LOWER(PA_PAT_NR) LIKE '".$text."%'
                        AND vs_ab_datum IN (SELECT MAX(vs_ab_datum)
                                                FROM versichertenstatus
                                                GROUP BY vs_pat_nr);";

Jetzt muss ich also nur noch irgendwie hin bekommen das ich über PHP die pa_pat_nr verglichen werden und wenn eine doppelt, oder mehrfach, vorkommt dann sie mit dem letzten Eintrag einfach zu überschreiben. Allerdings habe ich jetzt auch schon etwas getüftelt und komme allerdings auf keinen grünen Pfad. :-/

Mein derzeitiger PHP-Code würde so aussehen:

PHP:
while($zeile = ibase_fetch_row($dbabfrage))
    {
        echo '<tr>';

        for($j=0; $j<1; $j++)
        {
                echo '<td>' .(string)$zeile[0].
                        ', '.(string)$zeile[1].
                        '<span style="white-space:pre">	</span>'
                            .(string)$zeile[2].
                        '</td>';
        }

        for($j=3; $j<5; $j++)
        {
            echo '<td>' . (string)$zeile[$j] . '</td>';

            if(strlen($zeile[4]) >= '15')
            {
                $zeile[4]=substr($zeile[4], 0,15);
            }
        }

        if($zeile[5] == '1')
        {
            echo '<td> </td>';
        }
        elseif($zeile[5] == '2')
        {
            echo '<td>P</td>';
        }

        switch($zeile[6])
        {
            case '1':
                echo '<td>M</td>';
                break;

            case '3':
                echo '<td>F</td>';
                break;

            case '5':
                echo '<td>R</td>';
                break;

            default:
                echo '<td>-</td>';
                break;
        }

        echo '<td>' . (string)$zeile[7] . '</td>';

        for($j=8; $j<10; $j++)
        {
            echo '<td>' . (string)$zeile[$j] . '</td>';
        }

        echo '</tr>';
    }

Ich hätte es so versucht, das ich eben die $zeile[9] über einen count Befehl auszähle und vergleichen lasse und wenn sie mehr als einmal vorkommt vielleicht den vorangehenden String zu löschen, aber das hat irgendwie nicht funktioniert.
Jetzt wollte ich mal wissen ob mein Denkvorgang überhaupt richtig war, oder sollte ich doch lieber anders vorgehen?
 
Zuletzt bearbeitet von einem Moderator:
Dein SQL ist nicht sauber.
Du nimmst pro vs_pat_nr das MAX(). Und dann prüfst du nur noch ob das Datum in dieser Menge ist ohne die pat_nr zu vergleichen.

Bsp.
Code:
pat_nr | datum
1      | 2011-03-21
1      | 2011-03-20
1      | 2011-03-19
2      | 2011-03-20
Dein max() pro pat_nr ergibt die Daten 2011-03-21 (für pat_nr=1) und 2011-03-20 (für pat_nr=2)
Jetzt prüfst du jeden Eitrag gegen diese Tabelle ohne die pat_nr zu vergleichen. so findet er die beiden oben erwähnten Daten. Ergo wird für pat_nr 2011-03-21 und 2011-03-20 zurückgegeben. Das ist nicht das was du willst. Du musst auch noch die pat_nr vergleichen.

Ich habe für mysql mal einige möglichkeiten für solche Vergleiche als beispiel erstellt. Ev geht eines davon auch für FireBird:
MySQL Aktuelle Einträge pro Gruppe auslesen
 
Also, erst mal danke für den Link zu deinem Wiki!
Jetzt zu dem was ich sagen wollte: Ich habe jetzt einmal vorgehabt die SQL-Abfrage noch mal neu von Anfang an zu schreiben und bin nach deinem Beispiel vor gegangen:

SQL:
SELECT
    w1,
    w2,
    MAX(datum) AS max_datum
FROM
    kurs
GROUP BY
    w1,
    w2;

Das habe ich halt nur auf meine Abfrage angepasst:

SQL:
SELECT
	pa_name
	pa_vorname,
	pa_titel,
	substring(100+extract(DAY FROM pa_geb_datum)from 2 for 2)||
            '.'|| substring(100+extract(MONTH FROM pa_geb_datum)from 2 for 2)||
            '.'|| extract(YEAR FROM pa_geb_datum),
	vs_kas_bezeichnung,
	vs_versich_art,
	vs_mart,
	pa_behandler,
	pa_pat_nr,
	MAX(vs_ab_datum) AS max_vs_ab_datum
FROM
	patient,
	versichertenstatus
ORDER BY
	pa_name,
	pa_vorname;

Wenn ich das dann abspeichere und ausgeben lassen möchte, gibt er mir folgende Fehlermeldung aus:
Dynamic SQL Error SQL error code = -104 Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause)

Das bedeutet, wenn ich es jetzt richtig verstanden habe, ihm fehlt die GROUP BY-Anweisung!?
 
Zuletzt bearbeitet von einem Moderator:
Zurück