繁体   English   中英

组以逗号分隔的重复值

[英]Group comma-separated repeated values

我有一个带有这些值的表

SITE_NAME | CATEGORY |
----------------------
SITE1 | CAR, TRAVEL
SITE2 | TRAVEL
SITE3 | SPORT, GAME
SITE4 | GAME
SITE5 | CAR
SITE6 | TRAVEL
SITE7 | GAME

我希望它汇总重复的值,所以我正在使用它:

SELECT category, COUNT (*) FROM table_db group by category having count (*)> = 1

这适用于将相等的“类别”值分组,但是将“ CAR,TRAVEL”视为“ CAR”以外的值,我希望也将其标识为重复值。

此代码显示以下内容:

CAR, TRAVEL
TRAVEL
SPORT, GAME
CAR
GAME

我希望它看起来像这样:

CAR
TRAVEL
SPORT
GAME

我完全同意有关数据库设计的其他意见,但是,无论出于何种原因,如果您坚持使用自己的设计,那么就需要创建一个拆分函数。 像这样:

CREATE FUNCTION public.fnsplit(
    IN stringlist character varying,
    IN delimit character varying)
  RETURNS TABLE(items character varying) AS
$BODY$
declare remainderlist character varying;
declare front character varying;
declare delimitpos integer;
begin
    drop table if exists tmptbl;
    create temp table tmptbl(items character varying);
    remainderlist := $1;
    delimitpos := strpos(remainderlist, $2);
    while delimitpos > 0 loop
        front := trim(both from(left(remainderlist, delimitpos -1)));
        remainderlist := substr(remainderlist, delimitpos + 1);
        if length(front) > 0 then
            insert into tmptbl values (front);
        end if;
        delimitpos := strpos(remainderlist, $2);
    end loop;
    --insert last value
    remainderlist := trim(both from remainderlist);
    if length(remainderlist) > 0 then
        insert into tmptbl values (remainderlist);
    end if;
    return query
        select * from tmptbl;
        return;
end;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100
  ROWS 1000;

然后,您可以像这样在您的选择中使用它:

SELECT category, COUNT (*) FROM
(SELECT fnsplit(category, ', ') as category FROM table_db) d
group by category having count(*) >= 1;

我不禁要强调,这应该是不得已的方法!

编辑

已经指出,OP需要MySQL。 这有点棘手,因为MySQL不允许函数返回表。 因此,您必须使用临时表。 所以现在函数看起来像这样:

DELIMITER $$
CREATE PROCEDURE fnsplit(
    stringlist varchar(2000),
    delimit varchar(20)
) 
BEGIN

declare remainderlist varchar(2000);
declare front varchar(2000);
declare delimitpos integer;

    SET remainderlist = stringlist;
    SET delimitpos = position(delimit in remainderlist);
    while delimitpos > 0 do
        SET front = trim(both from(left(remainderlist, delimitpos -1)));
        SET remainderlist = substr(remainderlist, delimitpos + 1);
        if length(front) > 0 then
            insert into tblTmpSplit values (front);
        end if;
        SET delimitpos = position(delimit in remainderlist);
    end while;
    SET remainderlist = trim(both from remainderlist);
    if length(remainderlist) > 0 then
        insert into tblTmpSplit values (remainderlist);
    end if;

END$$
DELIMITER ;

您现在可以这样称呼它:

SET @allcategories = (SELECT GROUP_CONCAT(category separator ', ') FROM table_db);

drop table if exists tbltmpsplit;
create temporary table tbltmpsplit(items varchar(2000));

call fnsplit(@allcategories, ', ');

SELECT *, Count(*) FROM tbltmpsplit GROUP BY items having count(*) >= 1;

drop table if exists tbltmpsplit;

返回:

CAR 2
GAME    3
SPORT   1
TRAVEL  3

暂无
暂无

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

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