2011-01-11 13 views
0

Ich brauche nur eine Richtung auf diesem. Ich habe die folgenden Tabellen:MySQL dynamisch zusammenführen/auswählen Wählen Sie Zeilen

Table: entity 
- ID (INT) 

Table: attributes 
- ID (INT) 
- name (VARCHAR) 
- internalname (VARCHAR) 

Table: values 
- ID (INT) 
- entity (ID) 
- attributes (INT) 
- value (Text) 

Was ich will, ist ein Select Statement zu machen, die so etwas wie die folgenden zurück:

- ID = entity.ID 
- {attributes.internalname ID 1} = values.{attribe internalname 1}.value 
- {attributes.internalname ID 2} = values.{attribe internalname 2}.value 
- {attributes.internalname ID 3} = values.{attribe internalname 3}.value 
- {attributes.internalname ID n} = values.{attribe internalname n}.value 
- etc... 

Es wäre wie die Kombination von:

SELECT entity.id FROM entity; 

und

SELECT (SELECT values.value FROM values WHERE values.entity = entity.ID AND values.attributes = attributes.ID) FROM attributes; 

Es ist eine schwierige Sache zu erklären, aber wenn Sie mich weiter erklären müssen, lassen Sie es mich wissen.

Ich möchte effektiv alle Werte in Attributen zu Spalten drehen und alle Werte in den entsprechenden Attributwert mit der ID als Selektor drehen.

Ich gebe der Abfrage eine ID (das Element ID), und in einer Ergebniszeile gibt es alle Daten zurück.

Vielen Dank im Voraus!

+0

Ich sehe nicht, warum die Tabellenentität mit nur einer Spalte existiert, die bereits in der Tabelle Werte gespeichert ist – cfEngineers

+0

Es ist nur als ein Index, und einige Spalten können dort erscheinen. Dies ist tatsächlich sehr ähnlich zu Magento Commerce speichert seine Daten, Problem ist, dass sie Hunderte von Abfragen verwenden, um das gleiche Ergebnis, das ich versuche, in einem zu erreichen. – Nitroware

Antwort

2

Sie sich keine Spalten dynamisch erstellen können, so dass Sie wissen müssen, um im Voraus, was Sie als Spalten wollen.

Wenn Attribute (1,2,3,4) darstellen (Vorname, Nachname, extraname, additionalname) können Sie es wie folgt abfragen:

select e.id 
     ,v1.value as firstname 
     ,v2.value as lastname 
     ,v3.value as extraname 
     ,v4.value as additionalname 
    from entity e 
    left join values v1 on(e.id = v1.entity and v1.attributes = 1) 
    left join values v2 on(e.id = v2.entity and v2.attributes = 2) 
    left join values v3 on(e.id = v3.entity and v3.attributes = 3) 
    left join values v4 on(e.id = v4.entity and v4.attributes = 4) 
where e.id = ? 

oder

select e.id 
     ,max(case when v.attributes = 1 then value) as firstname 
     ,max(case when v.attributes = 2 then value) as lastname 
     ,max(case when v.attributes = 3 then value) as extraname 
     ,max(case when v.attributes = 4 then value) as additionalname 
    from entity e 
    left join values v on(e.id = v.entity) 
where v.attributes in(1,2,3,4) 
    and e.id = ? 
group by e.id; 

Sie können auch Verwenden Sie die GROUP_CONCAT, um die Werte in einer durch Kommas getrennten Liste in einer Spalte zurückzugeben.

select e.id 
     ,group_concat(v.value) 
    from entity e 
    left join values v on(e.id = v.entity) 
group 
    by e.id; 

Oh, und values ist ein reserviertes Wort. Verwenden Sie es nicht als Tabellenname.

Oh 2, verwenden Sie dieses Modell nicht, es sei denn Sie wirklich wirklich müssen. Sie zahlen einen großen, saftigen Preis in Bezug auf Leistung und Datenkonsistenz.

+0

Sie rocken! Danke, Mann! Welches Modell würden Sie dann für die Datenspeicherung empfehlen? Dies ist nur ein generisches Modell, das ich für verschiedene Elemente eines Systems verwenden wollte ... – Nitroware

0

Ich dulden keine Auswahl * also ersetzen Sie mit Ihren Spalten. Die Werte können ein reserviertes Schlüsselwort

select * 
    from values v 

    left join attributes a 
    on a.id = v.attributes 

    left join entity e 
    on e.id = v.entity 

    where 1=1 

    /* put your where clause here */ 
+0

Das ist sehr nah an dem, was ich wollte, aber ich möchte alle Daten in einer Zeile zurück. Ich habe meinen ursprünglichen Beitrag aktualisiert. Danke aber! – Nitroware

Verwandte Themen