获取MySQL WHERE IN分隔字符串

时间:2015-01-14 15:30:43

标签: php mysql laravel

我最近遇到了一个问题,我一直在将一串逗号分隔值发送到存储过程中。我的问题是,当我在PHP中执行我的存储过程时,它会像上面那样用引号上传值;

CALL `rankingInformation`('145', '5', '', '37,38,39,40,41')

未能添加引号会使MySQL将其解释为额外参数。

但是,在查询方面的WHERE IN中它的意思是,它的意思是这样格式化

'37', '38', '39', '40', '41'

以下是查询,有人能发现我能做的任何事吗?这就是我现在所做的。

CREATE DEFINER = `root`@` localhost` PROCEDURE` rankingInformation`(IN` surveyId` INT, IN` filterCounting` INT, IN` survey_filter_id` INT, IN` question_limit` TEXT)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT 'Gathers all the ranking information for a given ID'
BEGIN
DECLARE sfi int(2);
DECLARE ql TEXT;

IF(survey_filter_id = '') THEN
SET sfi = (SELECT sf2.survey_filter_id FROM survey_filters AS sf2 WHERE sf2.survey_id = 145 AND sf2.survey_filter_id IS NOT NULL LIMIT 1);
ELSE
SET sfi = survey_filter_id;
END IF;

SELECT
COUNT( * ) AS total, CONCAT(su.first_name, ' ', su.last_name) as full_name, sf.survey_filter_id, sf.survey_filter_name, qa.question_id, su.temp_group_1 AS department
FROM questions_answers AS qa
INNER JOIN survey_users AS su ON su.survey_users_id = qa.survey_users_id_answer
INNER JOIN survey_filters AS sf ON sf.survey_id = surveyId
WHERE qa.survey_id = surveyId
AND qa.question_id IN (splitAndTranslate(question_limit, ','))
AND sf.survey_filter_id = sfi
GROUP BY qa.survey_users_id_answer
HAVING total > filterCounting
ORDER BY total DESC;
END

splitAndTranslate 这是我发现的一个功能,这意味着要完成这项工作,我不确定我是不是很远。

CREATE DEFINER=`root`@`localhost` FUNCTION `splitAndTranslate`(`str` TEXT, `delim` VARCHAR(1))
RETURNS text CHARSET utf8
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT 'Fixes all Where IN issues'
BEGIN

DECLARE i INT DEFAULT 0;     -- total number of delimiters 
DECLARE ctr INT DEFAULT 0;     -- counter for the loop 
DECLARE str_len INT;          -- string length,self explanatory 
DECLARE out_str text DEFAULT '';     -- return string holder 
DECLARE temp_str text DEFAULT '';     -- temporary string holder 
DECLARE temp_val VARCHAR(255) DEFAULT '';     -- temporary string holder for query 

-- get length 
SET str_len=LENGTH(str);      

SET i = (LENGTH(str)-LENGTH(REPLACE(str, delim, '')))/LENGTH(delim) + 1;      
     -- get total number delimeters and add 1 
     -- add 1 since total separated values are 1 more than the number of delimiters 

-- start of while loop 
WHILE(ctr<i) DO 
     -- add 1 to the counter, which will also be used to get the value of the string 
     SET ctr=ctr+1;  

     -- get value separated by delimiter using ctr as the index 
     SET temp_str = REPLACE(SUBSTRING(SUBSTRING_INDEX(str, delim, ctr),    LENGTH(SUBSTRING_INDEX(str, delim,ctr - 1)) + 1), delim, ''); 

    -- query real value and insert into temporary value holder, temp_str contains the exploded ID               
    #SELECT ImageFileName INTO temp_val FROM custombu_roomassets_images WHERE ImageID=temp_str; 

    -- concat real value into output string separated by delimiter 
        SET out_str=CONCAT(out_str, temp_val, ','); 
END WHILE; 
-- end of while loop

-- trim delimiter from end of string 
SET out_str=TRIM(TRAILING delim FROM out_str); 
RETURN(out_str);     -- return

END

3 个答案:

答案 0 :(得分:1)

你用FIND_IN_SET做了什么?基于spencer7593的答案,如果你替换它应该有效:

AND qa.question_id IN (splitAndTranslate(question_limit, ','))

AND FIND_IN_SET(qa.question_id, question_limit)>0

答案 1 :(得分:0)

在SQL IN比较的上下文中,字符串值中的逗号被解释为SQL文本。您的查询基本上是以下形式:

AND qa.question_id IN ('some,long,string,value')

字符串中的任何逗号字符都只是数据;只是属于字符串的字符。这实际上与等于比较相同。


MySQL FIND_IN_SET函数可能是您进行所需比较的一种方式。

http://dev.mysql.com/doc/refman/5.5/en/string-functions.html#function_find-in-set

答案 2 :(得分:0)

AND qa.question_id IN (splitAndTranslate(question_limit, ','))

将这些行代替上面的行

AND (qa.question_id = question_limit
OR qa.question_id LIKE CONCAT(question_limit,',%')
OR qa.question_id LIKE CONCAT('%,',question_limit,',%')
OR qa.question_id LIKE CONCAT('%,',question_limit))

然后您不再需要splitAndTranslate函数。 。