2010-09-15 9 views
1

Je sélectionne les propriétés et les joignent aux tables de mappage où elles sont mappées à des filtres tels que l'emplacement, la destination et le type de propriété.Est-ce que j'utilise GROUP_CONCAT correctement?

Mon but est de récupérer toutes les propriétés, puis de les JOINDRE aux tables, puis d'obtenir des données qui montrent tous les emplacements, les destinations auxquelles une propriété est attachée et le type de propriété lui-même.

Voilà ma question:

SELECT p.slug          AS property_slug, 
     p.name          AS property_name, 
     p.founder          AS founder, 
     IF (p.display_city != '', display_city, city) AS city, 
     d.name          AS state, 
     type 
     GROUP_CONCAT(CONVERT(subcategories_id, CHAR(8))) AS foo, 
     GROUP_CONCAT(CONVERT(categories_id, CHAR(8))) AS bah 
    FROM properties AS p 
LEFT JOIN destinations AS d ON d.id = p.state 
LEFT JOIN regions AS r ON d.region_id = r.id 
LEFT JOIN properties_subcategories AS sc ON p.id = sc.properties_id 
LEFT JOIN categories_subcategories AS c ON c.subcategory_id = sc.subcategories_id 
    WHERE 1 = 1 
     AND p.is_active = 1  
GROUP BY p.id 

Avant de faire la GROUP BY et GROUP_CONCAT mes données ressemble à ceci:

id name     type  category_id subcategory_id state 
-------------------------------------------------------------------------- 
1 The Hilton Hotel  1  1    2     7 
1 The Hilton Hotel  1  1    3     7 
1 The BlaBla Resort  2  2    5     7 

Après la GROUP BY et GROUP_CONCAT il devient ...

id name     type  category_id subcategory_id state 
-------------------------------------------------------------------------- 
1 The Hilton Hotel  1  1, 1   2, 3    7 
1 The BlaBla Resort  2  1    3     7 

Est-ce la façon préférée de gra bbing tous les mappings possibles pour la propriété en une seule fois, avec GROUP_CONCAT dans un CSV comme ça?

Grâce à ces données, je peux rendre quelque chose comme ...

<div class="property" categories="1" subcategories="2,3"> 
    <h2>{property_name}</h2> 
    <span>{property_location}</span> 
</div> 

Utilisez ensuite Javascript pour afficher/cacher en fonction de si l'utilisateur clique sur un point d'ancrage qui a dit, un subcategory="2" attribut il se cacherait chaque .property qui n'a pas 2 à l'intérieur de sa valeur d'attribut subcategories.

Répondre

2

Je crois que vous voulez quelque chose comme ceci:

CREATE TABLE property (id INT NOT NULL PRIMARY KEY, name TEXT); 

INSERT 
INTO property 
VALUES 
     (1, 'Hilton'), 
     (2, 'Astoria'); 

CREATE TABLE category (id INT NOT NULL PRIMARY KEY, property INT NOT NULL); 

INSERT 
INTO category 
VALUES 
     (1, 1), 
     (2, 1), 
     (3, 2); 

CREATE TABLE subcategory (id INT NOT NULL PRIMARY KEY, category INT NOT NULL); 

INSERT 
INTO subcategory 
VALUES 
     (1, 1), 
     (2, 1), 
     (3, 2), 
     (5, 3), 
     (6, 3), 
     (7, 3); 


SELECT id, name, 
     CONCAT(
     '{', 
     (
     SELECT GROUP_CONCAT(
       '"', c.id, '": ' 
       '[', 
       (
       SELECT GROUP_CONCAT(sc.id ORDER BY sc.id SEPARATOR ', ') 
       FROM subcategory sc 
       WHERE sc.category = c.id 
       ), 
       ']' ORDER BY c.id SEPARATOR ', ') 
     FROM category c 
     WHERE c.property = p.id 
     ), '}') 
FROM property p; 

qui génèrerait ceci:

1 Hilton  {"1": [1, 2], "2": [3]} 
2 Astoria {"3": [5, 6, 7]} 

Le dernier champ est un bien formé JSON qui mappe catégorie id aux tableaux de ids sous-catégorie.

1

Vous devriez ajouter DISTINCT, et peut-être ORDER BY:

GROUP_CONCAT(DISTINCT CONVERT(subcategories_id, CHAR(8)) 
    ORDER BY subcategories_id) AS foo, 
GROUP_CONCAT(DISTINCT CONVERT(categories_id, CHAR(8)) 
    ORDER BY categories_id) AS bah 

Il est "normalisée de" si vous voulez l'appeler comme ça. Si c'est la meilleure représentation à utiliser pour le rendu est une autre question, je pense que c'est bien. Certains peuvent dire que c'est bidouiller, mais je suppose que ce n'est pas trop mal. Par ailleurs, une virgule semble manquer après le "type".