从同一个表中过滤逗号分隔值

时间:2015-02-26 11:45:04

标签: php mysql

Comma separated values not in id column

任何人都可以帮我从同一个表中获取不在id列中的sub_cat(csv)值。

(sub_cat)逗号分隔值是同一个表的id,我需要获取不在id列中的值。像id列中的2,3,7一样,而20,24则不存在。我只需要20,24。

2 个答案:

答案 0 :(得分:2)

正如我在this帖子中详细阐述的那样,我建议不要以CSV格式存储数据。 这样就无法访问和更新它。

我对此不太确定,但您可以简单地使用:

SELECT sub_cat FROM table_name WHERE id NOT IN (
    SELECT sub_cat FROM table_name
)

但是,我总是喜欢每行只存储一个ID。

答案 1 :(得分:1)

要在MySQL中完全做到这一点,需要编写存储过程;您需要将数据库名称test更改为数据库的实际名称。用PHP做这件事会好得多 - 但那里的乐趣在哪里?

DELIMITER //

CREATE PROCEDURE test.check_subcats(
    IN s_delimiter VARCHAR(30)
    )

    DETERMINISTIC
    READS SQL DATA

    BEGIN
        DECLARE s_csv TEXT;
        DECLARE i_subcat_index INT(10) unsigned DEFAULT 1;
        DECLARE i_subcat_count INT(10) unsigned;
        DECLARE l_category_done INT(10) DEFAULT FALSE;
        DECLARE c_category CURSOR FOR SELECT category.sub_cat FROM category;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_category_done = TRUE;

        -- create a temporary table to hold every csv value
        CREATE TEMPORARY TABLE IF NOT EXISTS tmp_csv( cvalue VARCHAR(10) NOT NULL );

        OPEN c_category;
        l_category: LOOP
            FETCH c_category INTO s_csv;

            IF l_category_done THEN
                LEAVE l_category;
            ELSE
                -- determine the number of sub-categories
                SELECT (LENGTH(s_csv) - LENGTH(REPLACE(s_csv, s_delimiter, ''))) + 1 INTO i_subcat_count;

                -- loop to store all csv values
                WHILE i_subcat_index <= i_subcat_count DO 
                    INSERT INTO tmp_csv ( cvalue ) (
                    SELECT REPLACE(SUBSTRING(
                            SUBSTRING_INDEX(s_csv, s_delimiter, i_subcat_index),
                            LENGTH(SUBSTRING_INDEX(s_csv, s_delimiter, i_subcat_index - 1)) + 1
                        ), s_delimiter, '')
                    );

                    SET i_subcat_index = i_subcat_index + 1;
                END WHILE;
            END IF;

            SET i_subcat_index = 1;
        END LOOP;       
        CLOSE c_category;

        SELECT DISTINCT tmp_csv.cvalue FROM tmp_csv WHERE tmp_csv.cvalue NOT IN ( SELECT category.id FROM category );
        DROP TEMPORARY TABLE IF EXISTS tmp_csv;
    END //

DELIMITER ;

我不是百分之百确定它有多强大,但它正在我的开发箱上使用你的数据。

您在调用此过程时指定CSV数据的分隔符:

CALL `check_subcats`(',');

基本上,这会循环遍历category表来阅读sub_cat。然后,它使用提供的分隔符将sub_cat值拆分为块(非常类似于PHP explode()函数),并将每个值写入临时表。

然后,这会为您提供一个临时表格,将您的所有CSV数据保存在各个位中,然后只需从NOT IN category.id {{1}} {{1}}数据中选择所有内容即可。列表。