2015-04-22 49 views
2

我需要你對這個自定義查詢的幫助,對我來說有點太難了。下面是MY_TABLE一個例子:MySQL查詢選擇與IF(xxxx已存在)遞歸

_______________________________ 
| item_name | item_slug | 
------------------------------- 
| Black Pant | pant_black | Select : pick first color, 'pant' doesn't exists 
| Red Pant  | pant_red  | Variation: 'pant_black' 
| Yellow Pant | pant_yellow | Variation: 'pant_black' 
| Tshirt  | tshirt  | Select : 'tshirt' exists 
| Tshirt Black | tshirt_black | Variation: 'tshirt' 
| Tshirt Red | tshirt_red | Variation: 'tshirt' 
| Tshirt Yellow| tshirt_yellow| Variation: 'tshirt' 
------------------------------- 

我試圖得到的結果是:

如果( 'T恤' & & 'tshirt_black' 存在):

不顯示 'tshirt_black' , 'tshirt_red', 'tshirt_yellow' 顏色,並把它們在一個 '變化' 陣列:

tshirt 
| Variations: 
|-> tshirt_black 
|-> tshirt_red 
|-> tshirt_yellow 

如果( '褲' 不存在& & 'pant_black' 存在):

以發現 'pant_black' 第一顏色,不顯示 'pant_red', 'pant_yellow' 顏色,並把它們在一個 '變化' 陣列:

pant_black 
| Variations: 
|-> pant_red 
|-> pant_yellow 

注意:'褲子'不存在,只有顏色存在。

我設法讓時無色名存在與此查詢(「T恤」),它的工作:

SELECT * FROM my_table WHERE item_name NOT LIKE '% Black' AND item_name NOT LIKE '% Red' AND item_name NOT LIKE '% Yellow' 

然後我申請一個PHP的foreach內的第二查詢()把「T恤」的變化在陣列。

SELECT * FROM my_table WHERE item_slug LIKE '$item_slug%' AND item_slug != '$item_slug' 

但我不能找到一個方法來遞歸檢查(「喘氣」 donesn't存在),然後使用發現爲「基地」的第一種顏色。例如'pant_black'。

完美的解決方案將是使其成爲一體化查詢。你怎麼看?

編輯:編輯我的帖子,只使用'item_slug'。

+0

我沒有看到你想要的結果與你說的查詢有什麼關係。你能否更好地解釋你想要的結果是什麼? –

+0

如果我不夠清楚,我很抱歉,我編輯了這篇文章,希望你現在能夠理解:) – hawkidoki

回答

2

如果您想要獲得兩個列,一個使用基本名稱,一個使用變量(或NULL)(如果它是基本名稱),則可以添加一個標誌以查找基本名稱。

也許這接近你想要什麼:

select ColorlessName, 
     (case when item_name <> ColorlessName then item_name end) as variation 
from (select t.*, 
      (select t2.item_name 
       from my_table t2 
       where substring_index(t2.item_slug, '_', 1) = substring_index(t.item_slug, '_', 1) 
       order by length(t2.item_name) desc, t2.item_name 
       limit 1 
      ) as ColorlessName 
     from my_table t 
    ) t 
order by ColorlessName, (variation is null) desc; 
+0

我認爲最好使用'item_slug'就像你在這裏描述的那樣。我不明白的是'無色名稱'列應該是什麼?它不存在於表 – hawkidoki

+0

@hawkidoki中。 。 。考慮到你的問題,這是我能想到的第一列的最好名字。 –

+0

好吧,出現錯誤「子查詢返回多於1行查詢....」 – hawkidoki

0

看起來你真的應該這樣數據是正確normalised充分利用關係數據庫的功能,如MySQL重新寫你的表模式。

看起來像item_slug相當於SKU

在此基礎上,我會重新寫你的架構沿着這些線路:

create table `products` (
    `product_id` int(10) unsigned not null AUTO_INCREMENT, 
    `product_name` varchar(64) not null, 
    `product_sku` varchar(32) not null, 
    PRIMARY KEY (`product_id`), 
    KEY `product_name_idx` (`product_name`), 
    KEY `product_sku_idx` (`product_sku`) 
) ENGINE=InnoDB CHARSET=utf8; 


create table `options` (
    `option_id` int(10) unsigned not null AUTO_INCREMENT, 
    `option_name` varchar(64) not null, 
    `option_value` varchar(64) not null, 
    PRIMARY KEY (`option_id`) 
) ENGINE=InnoDB CHARSET=utf8; 


create table `products_to_options` (
    `product_id` int(10) unsigned not null, 
    `option_id` int(10) unsigned not null, 
    PRIMARY KEY (`product_id`, `option_id`), 
    CONSTRAINT `product_id_idfk1` FOREIGN KEY (`product_id`) REFERENCES `products` (`product_id`) ON DELETE CASCADE, 
    CONSTRAINT `option_id_idfk1` FOREIGN KEY (`option_id`) REFERENCES `options` (`option_id`) 
) ENGINE=InnoDB CHARSET=utf8; 

添加一些數據:

INSERT INTO `options` (`option_name`, `option_value`) VALUES 
('colour','red'), 
('colour','yellow'), 
('colour','black'), 
('colour','green'), 
('colour','blue'), 
('size','S'), 
('size','M'), 
('size','L'); 

INSERT INTO `products` (`product_name`, `product_sku`) VALUES 
('T-Shirt', 'T-red-s'), 
('T-Shirt', 'T-red-m'), 
('T-Shirt', 'T-red-l'), 
('T-Shirt', 'T-green-s'), 
('T-Shirt', 'T-green-m'), 
('T-Shirt', 'T-green-l'), 
('T-Shirt', 'T'); 

INSERT INTO `products_to_options` (`product_id`, `option_id`) VALUES 
(1,1), 
(1,6), 
(2,1), 
(2,7), 
(3,1), 
(3,8), 
(4,4), 
(4,6), 
(5,4), 
(5,7), 
(6,4), 
(6,8); 

從那裏,這是一個簡單的查詢

-- get all products: 
SELECT 
    product_name, 
    product_sku, 
    IFNULL(group_concat(option_value), 'none') as attributes 
FROM products 
LEFT JOIN products_to_options USING(product_id) 
LEFT JOIN options USING(option_id) 
GROUP BY product_id 
ORDER BY NULL;