带有IF的MySQL查询SELECT(xxxx已经存在)递归

时间:2015-04-22 11:14:24

标签: php mysql sql

我需要你对这个自定义查询的帮助,对我来说有点太难了。以下是my_table的示例:

_______________________________
|  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'
-------------------------------

我试图获得的结果是:

如果('tshirt'&&'tshirt_black'存在):

不要显示'tshirt_black','tshirt_red','tshirt_yellow'颜色并将它们放在'variants'数组中:

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

如果('喘气'不存在&&'pant_black'存在):

找到第一个颜色'pant_black',不要显示'pant_red','pant_yellow'颜色并将它们放入'variants'数组中:

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

注意:'裤子'不存在,只有颜色存在。

我设法使用此查询存在无色名称('tshirt')时使其工作:

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

然后我在PHP foreach()中应用第二个查询,将'Tshirt'变体放在数组中。

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

但我无法找到一种方法来递归检查是否('喘气'不存在)然后使用第一个颜色找到“基地”。例如'pant_black'。

完美的解决方案是使其成为一体化查询。你觉得怎么样?

编辑:编辑我的帖子只使用'item_slug'。

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分: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;