mysql 统计符合字段值只能包含一种事件类型的记录

klr1opcd  于 2023-11-16  发布在  Mysql
关注(0)|答案(2)|浏览(96)

具有以下表格

CREATE TABLE contacts (
    Id INT NOT NULL AUTO_INCREMENT,
    Name varchar(255) NOT NULL,
    PRIMARY KEY(Id)
);

CREATE TABLE contacts_cstm (
    Id INT NOT NULL AUTO_INCREMENT,
    Id_c INT NOT NULL,
    Department_c varchar(255) NOT NULL,
    PRIMARY KEY(Id)
);

字符串
有这样的contacts_cstm数据

Id  Id_c    Department_c
1   1       ^pro^
2   2       ^pro^,^pro^
3   3       ^pro^,^temp^,^pro^


我想统计contacts_cstm表中的所有数据。其中department_c字段的值包括^pro^,或者像第二行一样有多个发生率的^pro^,但如果它包括与^pro ^不同的其他项目,则不应参与帐户
对于包含^pro^^pro^,^pro^的寄存器,预期输出为2
我创造了这个小提琴
Thanks in advance

aor9mmx1

aor9mmx11#

您的结构没有任何意义。在Department_c中存储逗号分隔的部门列表显然是一个坏主意(参见Is storing a delimited list in a database column really that bad?),并且需要字符串操作和全表扫描才能获得所需的答案。更糟糕的是,您将此序列化关系存储在一个单独的表中,该表具有无意义的代理PK,当你已经有了Id_c(大概是FK到contacts.Id?)。
从你的问题中并不完全清楚你在这里试图做什么,但似乎这些数据更好地表示为contacts (Id, Name)departments (Id, Name)contact_department (contact_id, department_id)。这可以更有效地查询,因为它可以有效地使用索引,而不是需要全表扫描。
也就是说,使用当前的结构,您可以通过删除外部count(*)的索引扫描来稍微改进P.Salmon's answer

SELECT COUNT(*)
FROM contacts_cstm
WHERE REPLACE(REPLACE(department_c, '^pro^', ''), ',', '') = '';

字符串
这里假设contacts_cstm中没有department_c为空字符串的行。如果空字符串是可能的情况,您可以添加一个条件来排除空字符串:

SELECT COUNT(*)
FROM contacts_cstm
WHERE REPLACE(REPLACE(department_c, '^pro^', ''), ',', '') = ''
AND department_c <> '';


这是db<>fiddle

8yoxcaq7

8yoxcaq72#

使用replace标识排除项

select count(*) - 
(SELECT  count(*) as exclusions from contacts_cstm
where replace(replace(department_c,'^pro^',''),',','') <> '') pros
from contacts_cstm;

字符串
https://dbfiddle.uk/5NVZIHaL

相关问题