MySQL регулярное выражение в подзапросе - PullRequest
0 голосов
/ 01 марта 2011

У меня очень специфическая проблема, и, просмотрев множество ресурсов, я не могу найти решение своей проблемы.

Версия MySQL, на которой я работаю, - MySQL 5.0.91

С учетом следующего определения таблиц:

DROP TABLE IF EXISTS `item`;
CREATE TABLE `item` (
  `id` int(11) NOT NULL default '0',
  `code` varchar(4096) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records 
-- ----------------------------
INSERT INTO `item` VALUES ('1', 'pizza|large|pepp');
INSERT INTO `item` VALUES ('3', 'pizza|medium|pepp');
INSERT INTO `item` VALUES ('2', 'pizza|small|pepp');
INSERT INTO `item` VALUES ('4', 'appetizer|fries|large');
INSERT INTO `item` VALUES ('5', 'beverage|2_liter|pepsi');
INSERT INTO `item` VALUES ('6', 'pizza|small|cheese');

DROP TABLE IF EXISTS `item_regexp`;
CREATE TABLE `item_regexp` (
  `id` int(11) NOT NULL default '0',
  `regexp` varchar(4096) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records 
-- ----------------------------
INSERT INTO `item_regexp` VALUES ('1', '((pizza)\\\\|)((large|medium)\\\\|)');
INSERT INTO `item_regexp` VALUES ('2', '((pizza)\\\\|)((.*)\\\\|)((alldressed))');
INSERT INTO `item_regexp` VALUES ('3', '((beverage)\\\\|)((2_liter)\\\\|)');
INSERT INTO `item_regexp` VALUES ('4', '((pizza)\\\\|)((.*)\\\\|)((pepp))');

В итоге элемент таблицы представляет элементы в счете-фактуре.В моем примере у меня есть 5 пунктов.Код является внутренним представлением этого конкретного элемента.

Затем таблица item_regexp используется для указания возможного продукта.Это может быть использовано, например, для захвата всех возможных продуктов, которые удовлетворяют заданному шаблону кода, чтобы применить скидку и т. Д.

Я хотел бы загрузить все записи item_regexp с количеством элементов, из которых каждый может получить данныесписок товаров на счете.

Выполнение подзапроса для подсчета количества записей в таблице item, которые были захвачены моим регулярным выражением, дает мне правильный результат:

################
# QUERY #1     #
################
SELECT 
(SELECT
count(*)
FROM
item
where 
`item`.`code` REGEXP '((pizza)\\|)((large|medium)\\|)') as "regexp1 count"
,
(SELECT
count(*)
FROM
item
where 
`item`.`code` REGEXP '((pizza)\\|)((.*)\\|)((alldressed))') as "regexp2 count"
,
(SELECT
count(*)
FROM
item
where 
`item`.`code` REGEXP '((beverage)\\|)((2_liter)\\|)') as "regexp3 count" 
,
(SELECT
count(*)
FROM
item
where 
`item`.`code` REGEXP '((pizza)\\|)((.*)\\|)((pepp))') as "regexp4 count" ;
+---------------+---------------+---------------+---------------+
| regexp1 count | regexp2 count | regexp3 count | regexp4 count |
+---------------+---------------+---------------+---------------+
|             2 |             0 |             1 |             3 |
+---------------+---------------+---------------+---------------+
1 row in set

Однако, выполнение этого подзапроса в пределахболее общий запрос, казалось, всегда давал 0 в качестве счетчика.Это как если бы регулярное выражение не работало или не принималось во внимание.

################
# QUERY #2     #
################
SELECT 
`item_regexp`.`regexp`
, 
(
SELECT
count(*)
FROM
item
where 
`item`.`code` REGEXP `item_regexp`.`regexp`
) as "regexp_count"
FROM 
item_regexp ;
+-------------------------------------+--------------+
| regexp                              | regexp_count |
+-------------------------------------+--------------+
| ((pizza)\\|)((large|medium)\\|)     |            0 |
| ((pizza)\\|)((.*)\\|)((alldressed)) |            0 |
| ((beverage)\\|)((2_liter)\\|)       |            0 |
| ((pizza)\\|)((.*)\\|)((pepp))       |            0 |
+-------------------------------------+--------------+
4 rows in set

Есть что-то, что я пропустил в этом процессе, так что QUERY # 2 выдает то же значение счетчика, что и QUERY # 1?

Спасибо за помощь.

Майк

1 Ответ

0 голосов
/ 01 марта 2011

Это потому, что когда вы определяете литерал

((beverage)\\|)((2_liter)\\|)

REGEXP видит двойное \ как единое целое.Когда вы помещаете его в столбец, они равны double \ s, поэтому он эквивалентен литералу

((beverage)\\\\|)((2_liter)\\\\|)

, что отличает их.Вы правильно сделали с литералами, но ваша вставка в item_regexp неверна.Попробуйте нижеприведенное

delete from `item_regexp`;
INSERT INTO `item_regexp` VALUES ('1', '((pizza)\\|)((large|medium)\\|)');
INSERT INTO `item_regexp` VALUES ('2', '((pizza)\\|)((.*)\\|)((alldressed))');
INSERT INTO `item_regexp` VALUES ('3', '((beverage)\\|)((2_liter)\\|)');
INSERT INTO `item_regexp` VALUES ('4', '((pizza)\\|)((.*)\\|)((pepp))');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...