Tabelle nur mit letztem Wert joinen

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Tabelle nur mit letztem Wert joinen

    Hi,

    ich habe lange gewartet, bis ich mich entschieden habe hier zu fragen, weil ich eigentlich keinen Einblick in meine Datenbankstruktur geben wollte, aber es hilft langsam nichts mehr. Ich weiß tatsächlich nicht weiter .. :D

    Hier erstmal die Tabellen:

    Quellcode

    1. [u]bank_accounts[/u]
    2. bank_account_id
    3. bank_account_owner_id
    4. bank_account_posessed_by_company
    5. bank_account_bank_id
    6. bank_account_bank_account_type_id
    7. bank_account_register_date
    8. [u]bank_account_credits[/u]
    9. bank_account_credit_bank_account_id
    10. bank_account_credit_num
    11. bank_account_credit_date
    12. bank_account_credit_change
    Alles anzeigen


    So.. es gibt also Bankkonten, die, wenn die UserID stimmt und bank_account_posessed_by_company gleich 0 ist, einer Person gehören. Eine Funktion soll nun ermitteln (die ich später für sajax brauche), wie das Gesamtvermögen des Benutzers aussieht. Über eine Funktion erhält die gesuchte Funktion bereits das Privatvermögen (aus einer anderen Tabelle). Nun sollen noch die Credits auf den Bankkontnen hinzugefügt werden.

    Ich brauche also ein MySQL-Statement, das alle Konten aus "bank_accounts" heraussucht und mit der dadurch erhaltenen bank_account_id aus bank_account_credits diejenigen credits herausholt, wo das Datum am aktuellsten (= größten ist).

    Bei einem einzigen Konto sehe das so aus:

    Quellcode

    1. SELECT
    2. `bank_account_credit_num`
    3. FROM
    4. `bank_account_credits`
    5. WHERE
    6. `bank_account_credit_bank_account_id` = '1'
    7. ORDER BY
    8. `bank_account_credit_date`
    9. LIMIT
    10. 1

    Da das neueste Datum stets am größten ist und er nur einen Datensatz holen soll, bekommt man genau den aktuellen Stand der Credits. Nun will ich das aber für alle Bankkonten gleichzeitig erledigen und zum Beispiel ein solches Ergebnis erhalten:

    Quellcode

    1. bank_account_id | bank_account_credit_num
    2. 1 | 10000
    3. 2 | 40345
    4. 3 | 66023

    Noch besser wäre natürlich sofort die Summe der drei Ergebnisse.

    Das Problem ist jetzt nur, dass ich, wenn ich mit JOINS oder sonstwas arbeite, zwar alles herausholen kann, er aber nicht mehr trennen kann, was der aktuellste Stand der Credits ist. Bei einem LIMIT 1 würde er ja schon nach einem ersten Treffer abbrechen, was ich natürlich nicht will.

    Fällt jemandem eine Idee ein, wie man per JOINs oder ähnlichem ohne zwei SQLs das Ergebnis erhalten kann?



    lG

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von PHP0Kid ()

  • Hm, ich finde das Tabellenlayout nicht perfekt.
    Den Stand würde ich nur einmal speichern, und die Transaktionen einfach mit soll/haben als Liste führen.
    Dann hättest du das Problem nicht.

    Es ist nicht ganz ersichtlich, aber vorausgesetzt, dass du die Relation über bank_accounts.bank_account_id = bank_account_credits.bank_account_credit_bank_account_id herstellst, habe ich hier zwei Lösungsvorschläge mit aktuellem Tabellenlayout für dich:

    1. Die syntaktisch einfache Subselect Lösung (mit n Selects)

    Quellcode

    1. SELECT *, (
    2. SELECT bank_account_credit_num
    3. FROM bank_account_credits
    4. WHERE bank_account_credit_bank_account_id = ba.bank_account_id
    5. ORDER BY bank_account_credit_date
    6. LIMIT 1
    7. ) AS bank_account_credit_num
    8. FROM bank_accounts;


    2. Die Lösung bei der wirklich nur 2 Selects ausgeführt werden... bei der GROUP BY reihenfolge bin ich mir allerdings nicht sicher - wird der aktuellste Wert verwendet?

    Quellcode

    1. SELECT *
    2. FROM bank_accounts
    3. NATURAL JOIN (
    4. SELECT bank_account_credit_bank_account_id AS bank_account_id,
    5. bank_account_credit_num AS credit
    6. FROM bank_account_credits
    7. GROUP BY bank_account_credit_bank_account_id
    8. ORDER BY bank_account_credit_date
    9. ) AS B;
  • Naja, bisher funktionierts noch nicht ganz - zumindest bringst du mich aber auf eine richtige Spur.

    Dein Tabellenlayoutvorschlag war mein erster Gedanke :) Diesen setze ich aber nicht um, weil ich auch Graphen über Veränderungen etc ausgeben lasse und dadurch Statistiken aufstelle. Das heißt jeder Eintrag bedeutet eine Veränderung. Das Problem bei einem neuen (bzw. deinem genannten) Layout wäre, dass die Information zwar sehr leicht abrufbar wäre, aber zugleich sämtliche alten Informationen verloren gehen.
    Bei den Tabellennamen nicht wundern - ich arbeite nach meinem eigenen entwickelten Standard. Kurz zusammengefasst regelt er, wie man eben Tabellen-/Spaltennamen benennt, so dass z.B. keine doppelten Spaltennamen in einer Datenbank auftreten und man Namen jederzeit logisch herleiten kann.

    Dein erster Vorschlag:
    Er funktioniert, nachdem ich aus ba.bank_account_id ein bank_account_id gemacht habe. Vielen Dank! Habe es mit "xx IN (neuer SELECT)" versucht, aber dann konnte er keine LIMITs hinerhalb machen, wodurch ich keine Lösung mehr gefunden habe! Vielen Dank :)

    Dein zweiter Vorschlag:
    Da hat er wegen irgendwelchen ALIAS-Namen gemeckert.. ich habe den Code auch nicht ganz verstanden, müsste es nochmal ausprobieren. Naja, solange der erste funktioniert, is es ja oke :)


    lG



    PS: klasse Reaktionszeit!
  • Den Tabellenalias schreibt man ohne AS dahinter (ist beim ersten auch schon falsch). AS verwendet man nur beim verändern Spaltennamen (wie bei dem Subselect im 2. Statement). Außerdem glaube ich du brauchst eine Verbundbedingung beim zweiten Statement, da du dort kein korrelierten Subselect bastelst sondern joinst und auch keine gleichnamigen Spalten hast. Bin mir aber nicht sicher wie das bei MySQL ist, vlt. nimmt er automatisch die Fremdschlüssel, was ich mir aber grade bei MySQL aber nicht vorstellen kann.

    Der Code ist zwar eh nicht mehr auf andere Datenbanken als MySQL portierbar, allerdings sollte man beim order by auch immer angeben ob asc oder desc, weil das bei anderen default-Einstellung zu viel Verwunderung führen kann.
    ~ mfg SeBa

    Ich beantworte keine PMs zu Computer-/Programmierproblemen. Bitte wendet euch an das entsprechende Forum.

    [Blockierte Grafik: http://i.creativecommons.org/l/by-sa/3.0/80x15.png]