2012-04-02 7 views
5

Ich habe ein System auf einer relationalen MySQL-Datenbank aufgebaut, die es ermöglicht, Details von "Leads" zu speichern. Darüber hinaus können Personen eigene Spalten erstellen, unter denen Daten gespeichert werden, und beim Hinzufügen neuer Konten können Daten unter ihnen hinzugefügt werden. Die Tabellenstruktur sieht wie folgt aus:Wie können "dynamische" Attribute, die in mehreren Zeilen gespeichert sind, als normale Datensätze abgerufen werden?

FÜHRT - id, E-Mail, User_id

ATTRIBUTES - id, attr_name, User_id

ATTR_VALUES - lead_id, attr_id, Wert, Benutzer-ID

Offensichtlich bezieht sich "user_id" in diesen Tabellen auf eine Tabelle "Benutzer", die nur Personen enthält, die sich beim System anmelden können.

Ich schreibe eine Funktion zur Ausgabe von Lead-Details und zacke gerade die grundlegenden Lead-Details als Abfrage und ziehe dann alle Attributwerte durch, die mit diesem Lead verknüpft sind (Verknüpfung mit der Attributtabelle, um den Namen zu erhalten) dann verbinden Sie die Arrays in PHP. Dies ist ein wenig unordentlich und ich frage mich, ob es eine Möglichkeit gibt, dies in einer SQL-Abfrage zu tun. Ich habe ein wenig über einen sogenannten "Pivot-Tisch" gelesen, aber ich habe Mühe zu verstehen, wie es funktioniert.

Jeder würde Hilfe sehr geschätzt. Vielen Dank!

+0

MySql unterstützt keine Pivot-Befehle. Äh, es ist kostenlos. – McGarnagle

+0

@dbase (Microsoft?) Mann: Nein * "Eh, es ist kostenlos" *, aber * "Eh, es ist eine Datenbank" * (im Gegensatz zu ...). Pivot-Befehle gehören nicht zur Datenbank, sondern zur Präsentationsebene. – TMS

+0

Gute Frage, obwohl der Titel irreführend war - es ist möglich, in einer einzigen Abfrage ganz einfach, nur in der Regel alle Tabellen beitreten - aber das ist nicht das, was Sie wahrscheinlich wollen. Bearbeitete den Titel. – TMS

Antwort

0

Ich würde mir das link ansehen. Das erklärt den Grund eines Dreh:

„Pivot-Tabelle“ oder eine „Kreuztabellen- Bericht“ SQL Charakteristische Funktionen: Sie es ohne „wenn“, „Fall“ oder „GROUP_CONCAT“. Ja, es gibt Verwendung für diese ... "if" -Anweisungen verursachen manchmal Probleme bei der Verwendung in Kombination. Das einfache Geheimnis, und es ist auch, warum sie in fast alle Datenbanken arbeiten, ist die folgenden Funktionen: sign (x) gibt -1,0, +1 für Werte x < 0, x = 0, x> 0 bzw. abs (sign (x)) liefert 0 wenn x = 0 sonst, 1, wenn x> 0 oder x < 0 1-abs (sign (x)) Komplement der oben, da dies 1 liefert nur dann, wenn x = 0

Es ist auch eine einfachere Möglichkeit, Prüfungen zu schwenken. Vielleicht kann das Licht darüber werfen?

1

Sie konnten die Verschwenkung in einer einzigen Abfrage wie folgt tun:

select l.id lead_id, 
     l.email, 
     group_concat(distinct case when a.attr_name = 'Home Phone' then v.value end) HomePhone, 
     ... 
from leads l 
left join attr_values v on l.id = v.lead_id 
left join attributes a on v.attr_id = a.id 
group by l.id 

Sie erhalten eine separate group_concat-abgeleitetes Feld umfassen müssen für jedes Attribut, das Sie anzeigen möchten.

0

Was Sie wahrscheinlich von mysql wollen, ist einen SQL-Wert (attr_name in Ihrem Fall) eine Spalte zu machen. Dieses Prinzip heißt pivot table (manchmal auch Kreuztabellen oder Kreuztabellenabfragen) und wird von mysql nicht unterstützt. Nicht, weil mysql nicht ausreicht, sondern weil die Pivotoperation keine Datenbankoperation ist - das Ergebnis ist keine normale Datenbanktabelle und ist nicht für weitere Datenbankoperationen.Der einzige Zweck der Pivot-Operation eine Präsentation - deshalb gehört es zu Präsentationsschicht, keine Datenbank.

So wird jede Lösung, die versucht, eine Pivot-Tabelle von MySQL zu bekommen, immer hacky sein. Was ich empfehlen ist es, die Daten aus der Datenbank im normalen Format zu bekommen, indem man einfach so etwas wie tun:

select * 
from attr_values join attributes using on attr_id = attributes.id 
    join leads on leads.id = lead_id 

und dann die Datenbankausgabe in der Präsentation Sprache (PHP, JSP, Python oder was auch immer Sie verwenden) zu transformieren.

0

Ich gehe vorsichtig davon aus, dass Pivot das Ziel der Vereinfachung erreichen wird. Pivot funktioniert nur, wenn Sie attr_name konsistent sind. Da Sie eine Benutzer-ID an sie gebunden haben, nehme ich an, dass dies nicht der Fall ist. Darüber hinaus haben Sie mehrere Werte für einen attr_name. Ich fürchte, Pivot-Tabelle würde nicht das Ergebnis produzieren, das Sie suchen.

Ich würde vorschlagen, dass Sie Ihre Transaktions- und Berichtstabellen getrennt halten. Haben Sie eine ETL-Routine, die bereinigt (dh, Attr_Name und Attr_value) konsistent durch die bersetzung. Dadurch werden Ihre Berichte aussagekräftiger.

Zusammengefasst ist PHP für die sofortige Ausgabe an den Endbenutzer das Beste, was Sie tun können. Um Berichte zu erstellen, transformieren Sie den EAV zuerst in eine Zeile/Spalte, bevor Sie versuchen, darüber zu berichten.