Wie wähle ich eine “falsche” Spalte/einen “falschen” Wert basierend auf verbundenen Tabellenwerten aus?

Lesezeit: 4 Minuten

Benutzer-Avatar
Radley Sustaire

Kurzversion:

Ich muss das Ergebnis einer Abfrage anpassen, indem ich einen Wert als Spaltennamen und einen anderen Wert als Spaltenwert verwende. Es muss auch automatisch sein (nicht fest codiert, Hunderte von möglichen “Meta-Schlüsseln”).

Lange Version:

Ich verwende die “Benutzer-Meta”-Struktur von WordPress, in der ein einzelner Benutzer eine Benutzer-ID hat und eine andere Tabelle “Meta-Daten” enthält, die sich auf den Benutzer beziehen.

Diese Metadaten sind willkürlich und haben nur vier Spalten:

meta_id, post_id, meta_key, meta_value.

Ich möchte eine SQL-Abfrage für einen bestimmten Benutzer durchführen und die Ergebnisse so formatieren, dass alle Metadaten so formatiert sind, als wären sie Zeilen, wobei die meta_key ein Spaltenname ist und meta_value ist der Wert für die Spalte.


Beispieldatenbank:

-- wp_users
* ID    | username | email
35      | radgh    | [email protected]

-- wp_usermeta
* meta_id | user_id | meta_key   | meta_value
1         | 35      | first-name | Radley
2         | 35      | last-name  | Sustaire
3         | 35      | newsletter | on

Meine Anfrage (Ich muss den (???)-Teil herausfinden, der die Meta-Schlüssel/Wert-Paare als gefälschte Spalten generieren würde.)

 SELECT 
    `users`.ID as 'user_id',
    `users`.username as 'username',
    `users`.email as 'email',
    (???)

 FROM `wp_users` `users`
     INNER JOIN `wp_usermeta` `meta`
     ON `users`.ID = `meta`.user_id

 WHERE `wp_users`.ID = 35

Gewünschtes Ergebnis:

* user_id | username | email             | first-name | last-name | newsletter
35        | radgh    | [email protected] | Radley     | Sustaire  | on

In dieser ähnlichen Frage verwendet die ausgewählte Antwort fest codierte Felder. Ich möchte dies automatisch tun. 🙂

  • Nehmen Sie die ‘myfakecolumn’ und versuchen Sie auch, diese Logik anzuwenden. [stackoverflow.com/questions/15091330/… [1]: stackoverflow.com/questions/15091330/…

    – RazorSky

    6. August 2013 um 20:24 Uhr

MySQL hat keine Pivot-Funktion. Wenn Sie bereits alle möglichen Werte von meta_key kennen, könnten Sie eine hartcodierte Abfrage wie diese verwenden:

SELECT
  wp_users.*,
  MAX(CASE WHEN `meta_key`='first-name' THEN meta_value END) AS `first-name`,
  MAX(CASE WHEN `meta_key`='last-name' THEN meta_value END) AS `last-name`,
  ....
FROM
  wp_users INNER JOIN wp_usermeta
  ON wp_users.ID=wp_usermeta.user_id
GROUP BY
  wp_users.ID, wp_users.username, wp_users.email;

Oder Sie könnten Ihre SQL-Abfrage dynamisch erstellen, indem Sie eine vorbereitete Anweisung wie diese verwenden:

SELECT
  CONCAT(
    'SELECT wp_users.*,',
    GROUP_CONCAT(
      CONCAT(
        'MAX(CASE WHEN `meta_key`=\'',
        meta_key,
        '\' THEN meta_value END) AS `',
        meta_key,
        '`')),
    ' FROM wp_users INNER JOIN wp_usermeta ON wp_users.ID=wp_usermeta.user_id',
    ' GROUP BY wp_users.ID, wp_users.username, wp_users.email')
FROM
  (SELECT DISTINCT meta_key FROM wp_usermeta) s
INTO @sql;

PREPARE stmt FROM @sql;
EXECUTE stmt;

Siehe Geige hier.

  • Ich habe darüber nachgedacht und könnte zwei Abfragen verwenden, eine, die alle möglichen Metaschlüssel sammelt, und dann PHP verwenden, um die zweite Abfrage wie in Ihrem Beispiel Nr. 1 zu erstellen. Ich habe jedoch gerade mit # 2 gespielt und eine neue Reihe erstellt, und es scheint so zu funktionieren, wie ich es von Anfang an wollte. Auch wenn es etwas schwer zu lesen ist ;). Hätte Option Nr. 1 einen großen Vorteil gegenüber Nr. 2? Ich vermute, #2 wird viele SELECT-Abfragen machen, aber Leistung ist hier nicht erforderlich – dieses Skript wird nicht regelmäßig verwendet.

    – Radley Sustaire

    6. August 2013 um 20:47 Uhr

  • Ich konnte die zweite Option nicht bekommen, um mit HeidiSQL (nicht dass die Anwendung wichtig ist) unter MySQL 5.1.54 zu arbeiten. Es ist jedoch nicht erforderlich, es zu debuggen, da ich letztendlich mit Option Nr. 1 mit meiner Idee aus dem letzten Kommentar gegangen bin. Tatsächlich hatte das Plugin (für WordPress), das diese Felder speicherte, eine globale Variable mit allen Feldnamen, sodass ich am Ende nicht einmal eine zusätzliche Abfrage benötigte und mich nicht um all die unnötigen Felder kümmern musste – nur das, was gerade verfügbar ist. Am Ende denke ich, dass dies sowieso die beste Option war. Vielen Dank für die Beispielabfragen!

    – Radley Sustaire

    7. August 2013 um 16:51 Uhr


Benutzer-Avatar
kwarunek

Es wird genannt Entitäts-Attribut-Wert-Modell. Eine Lösung für dynamische Spalten (Metadaten) in MySQL über eine einfache/komplexe Abfrage ist AFAIK unmöglich zu erreichen (wie andere großartige Funktionen wie PIVOT MySQL fehlt). Der einzige Weg, den ich denke, ist statische Definition oder MySQL-Funktiondie mögliche Attribute aus der Metatabelle abrufen und die richtige Abfrage erstellen.

Bitte sehen Sie sich an, was die beste Leistung zum Abrufen von MySQL EAV-Ergebnissen als relationale Tabelle ist

Lesen Sie auch über das EAV-Design (Vor-/Nachteile) im Stack Entity-Attribute-Value Table Design

  • So viel Fachjargon zu lernen, kein Wunder, dass ich so viel Mühe hatte, ähnliche Fragen zu finden! Das werde ich mal recherchieren, danke! Da es möglicherweise unmöglich ist, wäre es vielleicht der richtige Weg, eine separate Abfrage durchzuführen, nur um jeden Metaschlüssel zu finden, und ihn dann mit PHP in einem “fest codierten” Layout zu formatieren.

    – Radley Sustaire

    6. August 2013 um 20:30 Uhr

1252430cookie-checkWie wähle ich eine “falsche” Spalte/einen “falschen” Wert basierend auf verbundenen Tabellenwerten aus?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy