2011-03-01 43 views
0

我有一個非常特殊的問題,在查看很多資源後,我無法找到解決問題的方法。子查詢中的MySQL正則表達式

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 

有什麼我已經錯過了它的進程,使查詢#2 - 產率相同的計數值作爲QUERY#1?

感謝您的幫助。

邁克

回答

0

這是因爲當你定義一個文字

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

REGEXP看到雙\作爲唯一。 當你把它放在一列,他們是雙\ 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))'); 
+0

太棒了!我完全錯過了「\\」的逃避力量,現在它像魔術一樣工作。我將不得不重新考慮我的序列是如何被PHP和MySQL存儲和使用的。 謝謝你的幫助 – MQuirion 2011-03-01 21:58:07