2016-07-12 14 views
-1

2つのフィールド(key => valueなど)を「連結」する方法を見つける必要があります。 たとえば、そのクエリでは、(fielddef_id = 4 => fieldval.value = "Documentstéléchargeables")AND(fielddef_id = 5 => fieldval.value = "Anglais")の項目のみを表示します。店舗fielddefジョイントフィールドとカスタムフィールドを持つ複雑なmySQLクエリ

表キー 表フィールド値値を格納

しかし、多くの組み合わせがあります:キー=値...(例:LANG =英語、タイプ= downolad)

SELECT item.item_id AS id, item.title AS title, item.active AS active, item_cat.category_id AS cat_id, item_cat.item_id AS item_id, category.category_id, category.category_name as cat_name, category.category_alias as cat_alias 
FROM `cms_module_listit2ressources_item` AS item 
LEFT JOIN `cms_module_listit2ressources_item_categories` AS item_cat 
ON item.item_id = item_cat.item_id 
LEFT JOIN `cms_module_listit2ressources_category` AS category 
ON item_cat.category_id = category.category_id 
LEFT JOIN `cms_module_listit2ressources_fieldval` AS fieldval 
ON item.item_id = fieldval.item_id 
LEFT JOIN `cms_module_listit2ressources_fielddef` AS fielddef 
ON fieldval.fielddef_id = fielddef.fielddef_id 
WHERE item.active=1 
AND (fielddef.fielddef_id="4" AND fieldval.value IN ("Documents téléchargeables")) 
AND (fielddef.fielddef_id="5" AND fieldval.value IN ("Anglais")) 

これは簡単な例です。私は何をしたいのかを教えてくれます...データベースの概念を変更することはできません。

TABLE ITEMS Store the ID and Title of an item. 
id= INT/Primary/auto_increment 
title = VARCHAR (255) 

各項目には、多くのカスタムフィールドを持っている(例:「色=赤」、「国=フランス」、等。)私は、WHERE色=赤、国=フランス

項目のみをリストする必要が

TABLE CUSTOM_FIELDNAME Stores the fieldname (definition => example : "Color", "Country") 
fielddef_id = INT/PRIMARY/auto_increment 
name = VARCHAR(255) (=> ex: Color, Country...) 

TABLE CUSTOM_FIELDVALUE stores the field value (example : "red", "France") 
item_id => foreign_key to link to the ITEMS TABLE 
fielddef_id => foreign_key to link to the CUSTOM_FIELDNAME TABLE 
value = VARCHAR(255) (=> ex: red, France...) 

サンプル件のデータ:

TABLE ITEMS : 
id=1 | Title = "first Item" 
id=2 | Title = "A red French Item" 

TABLE CUSTOM_FIELDNAME 
fielddef_id = 1 | name = "Color" 
fielddef_id = 2 | name = "Country" 

TABLE CUSTOM_FIELDVALUE 
item_id = 1 | fielddef_id = 1 | value = "Blue" 
item_id = 1 | fielddef_id = 2 | value = "Germany" 
item_id = 2 | fielddef_id = 1 | value = "Red" 
item_id = 2 | fielddef_id = 2 | value = "France" 

だから私のクエリは次のようになります。

SELECT items.title AS title 
custom_fieldname.name as customName 
custom_fieldvalue.value as customValue 
FROM `items` 
LEFT JOIN `custom_fieldvalue` 
ON items.id = custom_fieldvalue.item_id 
LEFT JOIN `custom_fieldname` 
ON custom_fieldvalue.fielddef_id = custom_fieldname.fielddef_id 
WHERE(custom_fieldname.fielddef_id="1" AND custom_fieldvalue.value "Red") AND (custom_fieldname.fielddef_id="2" AND custom_fieldvalue.value "France") 
+0

Plsはいくつかのサンプルを提供しますデータおよび予測された出力を含む。現在あなたの質問は私には分かりません。私が推測しなければならないのであれば、あなたはgroup_concat()を探しています。 – Shadow

+0

ON句にLEFT JOIN条件を入れることについての佐賀の指摘を受けて、1つのオプションは、fielddefとfiedvalのテーブルを条件ごとに1回ずつLEFT JOINすることです。他のオプションは、典型的なピボットクエリの古典的な 'MAX(CASE WHEN ...)'シンタックスに比べて遅いが読みやすくなります。 – Strawberry

答えて

0

例:

SELECT i.item_id AS id 
    , item.title AS title 
    , item.active AS active 
    , item_cat.category_id AS cat_id 
    , item_cat.item_id AS item_id 
    , category.category_id 
    , category.category_name as cat_name 
    , category.category_alias as cat_alias 
    , v4.value v4_value 
    , d4.fielddef_id d4_fielddef_id 
    , v5.value v5_value 
    , d5.fielddef_id d5_fielddef_id 
    FROM cms_module_listit2ressources_item i 
    LEFT 
    JOIN cms_module_listit2ressources_item_categories ic 
    ON ic.item_id = i.item_id 
    LEFT 
    JOIN cms_module_listit2ressources_category c 
    ON c.category_id = ic.category_id 
    LEFT 
    JOIN cms_module_listit2ressources_fieldval v4 
    ON v4.item_id = i.item_id 
    AND v4.value IN ("Documents téléchargeables") 
    LEFT 
    JOIN cms_module_listit2ressources_fielddef d4 
    ON d4.fielddef_id = v4.fielddef_id 
    AND d4.fielddef_id = 4 
    LEFT 
    JOIN cms_module_listit2ressources_fieldval v5 
    ON v5.item_id = i.item_id 
    AND v5.value IN ("Anglais") 
    LEFT 
    JOIN cms_module_listit2ressources_fielddef d5 
    ON d5.fielddef_id = v5.fielddef_id 
    AND d5.fielddef_id = 5 
WHERE i.active = 1; 
+0

ありがとう、これは動作します!私は、LEFT JOINをINNER JOINに置き換えて、両方の条件が完了したときにのみ一致させました! –

1

最初に、LEFT JOINの右側の表の条件をWHERE節に置くと、それらはON()句にのみ置く必要があります。

第2に、あなたの最後の条件は意味を持たず、常にFALSEになります。フィールドは一度に1つ以上の値に等しいことはできません。

第3に、文字列の比較は一重引用符'で行い、二重ではないを使用する必要があります。

そして最後に、あなたは、CONCAT()を使用する必要があります(私はあなたがそれを少し調整する必要がありますと仮定)は、このような何かを試してみてください。

SELECT CONCAT(First_Field,'=>',Second_Field) 
FROM `cms_module_listit2ressources_item` AS item 
LEFT JOIN `cms_module_listit2ressources_item_categories` AS item_cat 
ON item.item_id = item_cat.item_id 
LEFT JOIN `cms_module_listit2ressources_category` AS category 
ON item_cat.category_id = category.category_id 
LEFT JOIN `cms_module_listit2ressources_fieldval` AS fieldval 
ON item.item_id = fieldval.item_id 
LEFT JOIN `cms_module_listit2ressources_fielddef` AS fielddef 
ON fieldval.fielddef_id = fielddef.fielddef_id  AND 
    (fielddef.fielddef_id,fieldval.value) IN(('4','Documents téléchargeables), 
              ('5','Anglais')) 
WHERE item.active=1 
+0

CONCATを使用しないでください。何のためでもない。これまで – Strawberry

+0

通常、このようなことを言うときは、理由を説明する必要があります。 – sagi

+0

CONCATとGROUP_CONCATはSQLデータのアトミック性を損なうためです。アプリケーションレベルのコードではより効果的に実行できない機能では、(ほとんど)何もできません。 – Strawberry