2009-11-06 6 views
4

Je crée un site dans wordpress qui contient des informations sur les programmes de télévision. J'utilise des champs personnalisés pour sélectionner chaque message.Requête MySQL compliquée

Le tableau ressemble à ceci

+----+---------+----------+------------+ 
| id | post_id | meta_key | meta_value | 
+----+---------+----------+------------+ 
| 1 | 1 | name | Smallville | 
| 2 | 1 | season |  1  | 
| 3 | 1 | episode |  1  | 
| 4 | 2 | name | Smallville | 
| 5 | 2 | season |  1  | 
| 6 | 2 | episode |  2  | 
+----+---------+----------+------------+ 

En fait ce que je dois faire est de sélectionner toutes les émissions de télévision avec le nom « Smallville » et les trier par saison puis par épisodes. Je pensais que ce serait assez simple mais tout ce que j'ai essayé ne retourne rien.

Pourriez-vous m'expliquer comment je peux faire cela?

+1

Avez-vous le contrôle sur la base de données pour le transformer en un format plus normal? Ou est-ce hors de question? – dustmachine

+0

Pourquoi oh pourquoi utiliser un format de tableau comme celui-ci? –

+0

Malheureusement, pas Dustmachine, j'utilise Wordpress. –

Répondre

11

Vous pouvez faire quelque chose comme ceci:

SELECT 
    t1.post_id, 
    t1.meta_value AS name, 
    t2.meta_value AS season, 
    t3.meta_value AS episode 
FROM 
    (
    SELECT * 
    FROM the_table 
    WHERE meta_key = 'name' 
    ) t1 
INNER JOIN 
    (
    SELECT * 
    FROM the_table 
    WHERE meta_key = 'season' 
    ) t2 ON t1.post_id = t2.post_id 
INNER JOIN 
    (
    SELECT * 
    FROM the_table 
    WHERE meta_key = 'episode' 
    ) t3 ON t1.post_id = t3.post_id 

Cela donnera vous le résultat:

| post_id | name  | season | episode | 
------------------------------------------- 
| 1 | Smallville | 1  | 1  | 
| 2 | Smallville | 1  | 2  | 

Sous cette forme, il est beaucoup plus facile pour toutes les opérations.

Qu'est-ce que vous avez besoin est d'ajouter:

WHERE name = 'Smallville' 
ORDER BY season, episode 
+1

@Lukasz - vous avez une petite erreur - la liste SELECT doit être: t1.post_id, t1.meta_value AS nom, t2.meta_value AS saison, t3.meta_value AS épisode. –

+0

Ohhh, vous avez tellement raison! Merci. –

2

Un cas plus général: tri de la conversion de votre format à un format de base de données relationnelle plus normal:

SELECT (SELECT meta_value FROM data t1 WHERE t1.post_id = t0.post_id AND meta_key = "season") AS season, 
    (SELECT meta_value FROM data t1 WHERE t1.post_id = t0.post_id AND meta_key = "episode") AS episode 
FROM data t0 WHERE meta_key = "name" AND meta_value = "Smallville" 

Pour le tri réel que vous ne pouvez pas réutiliser les valeurs saison/épisode (ce ne sont pas encore attribuée lors du tri), de sorte que vous devez copier/coller dans la sous-requête la clause ORDER BY:

ORDER BY (SELECT ... "season") ASC, (SELECT ... "episode") ASC, 
7

Combiner les lignes à l'aide d'un auto-jointure, et vous êtes bon pour aller:

SELECT  * 
FROM  yourtable name 
INNER JOIN yourtable season 
      on season.post_id = name.post_id 
      and season.meta_key = 'season' 
INNER JOIN yourtable episode 
      on episode.post_id = name.post_id 
      and episode.meta_key = 'episode' 
WHERE  name.meta_key = 'name' 
      and name.meta_value = 'Smallville' 
ORDER BY season.meta_value, episode.meta_value 
+0

Beau travail Andomar. Convertis ceci en un autre exemple à: http: //codex.wordpress.org/Function_Reference/wpdb_Class # SELECT_a_Column – Michael

1

l'idée est de se joindre à la table elle-même 3 fois où pour chacun d'entre eux prennent des lignes pour une meta_key donnée:

SELECT t1.meta_value name, t2.meta_value season, t3.meta_value episode 
FROM table t1 
JOIN table t2 on t1.post_id = t2.post_id and t2.meta_key = 'season' 
JOIN table t3 on t1.post_id = t3.post_id and t3.meta_key = 'episode' 
WHERE t1.meta_key = 'name' 
    AND t1.meta_value = 'Smallville' 
ORDER BY t2.meta_value, t3.meta_value 
2

Pas besoin de faire SQL directe. Vous avez accès à la requête SQL via l'objet WP_Query. Consultez les filtres entourant la clause where dans l'objet WP_Query (il y a plus d'une façon de l'obtenir) et modifiez simplement les parties WP_Query par défaut avant de les concaténer ensemble. Commencez par configurer un objet WP_Query qui reçoit tous les messages par la valeur postmeta & de postmeta, puis ajoutez un peu plus à la clause where pour ajouter des conditions supplémentaires.

Il existe un autre filtre qui vous permet d'accéder à la section de commande de la requête SQL afin de pouvoir la modifier.

Il n'y a pas de raison d'écrire du SQL ici, il suffit de modifier ce qui a déjà été construit pour vous.