繁体   English   中英

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

[英]Filter comma separated values from same table

逗号分隔的值不在id列中

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

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

正如我在这篇文章中详细阐述的那样,我建议不要以CSV格式存储数据。 这使得访问和更新它变得困难。

我不确定这一点,但您可以简单地使用:

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

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

纯粹在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值拆分为块(非常类似于PHPs explode()函数),并将每个值写入临时表。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM