【问题标题】:Count occurence of attribute values in each row with case-sensitive in sql在sql中使用区分大小写的方式计算每行中属性值的出现次数
【发布时间】:2020-08-19 02:46:42
【问题描述】:

我有表格(notes_subject)结构 -

+--------------+-------------+------+-----+---------+----------------+
| Field        | Type        | Null | Key | Default | Extra          |
+--------------+-------------+------+-----+---------+----------------+
| id           | int         | NO   | PRI | NULL    | auto_increment |
| user_id      | int         | NO   |     | NULL    |                |
| note_id      | varchar(25) | NO   | MUL | NULL    |                |
| subject_name | text        | NO   |     | NULL    |                |
+--------------+-------------+------+-----+---------+----------------+

以及存储在此表中的数据 -

+----+---------+--------------+--------------+
| id | user_id | note_id      | subject_name |
+----+---------+--------------+--------------+
| 10 |       2 | UdMs870BSswp | CN           |
| 12 |       2 | 8stMvslwIGr2 | CN           |
| 13 |       2 | PB3KNbbFkaUm | cn           |
+----+---------+--------------+--------------+

注意:CN 和 cn(小写)不同。

我想通过user_id 来统计每个subject_name 在此表中的出现次数。所以我运行查询 -

SELECT subject_name, COUNT(subject_name) 
FROM notes_subject where user_id=2 GROUP BY subject_name;

它成功了 -

+--------------+---------------------+
| subject_name | COUNT(subject_name) |
+--------------+---------------------+
| CN           |                   3 |
+--------------+---------------------+

但这不是正确的结果,因为 CN 和 cn 不同。
我还想要结果中的 id、user_id、note_id。

【问题讨论】:

  • 这可能与排序规则有关。我建议搜索类似How to do a case sensitive GROUP BY? 的内容。但这个问题是特定于 SQL Server 的,因此可能会因您的数据库而异。
  • @HernánAlarcón 我试过这个查询 - SELECT subject_name, COUNT(subject_name) FROM notes_subject GROUP BY subject_name COLLATE SQL_Latin1_General_CP1_CS_AS 但它给出了错误
  • stackoverflow.com/questions/5629111/… 是否回答您的问题
  • @HernánAlarcón Unknown collation 发生错误,我在您共享的链接中看到了已接受的答案。他正在为每一行手动提供所有值
  • @carljohnson 你的数据库是什么? SQL 是一种语言

标签: mysql sql case-sensitive


【解决方案1】:

如果你的数据库支持window functions,我想你想要这样的东西。尝试使用collate utf8mb4_bin 看看这是否有助于您需要区分大小写

select id, 
       user_id, 
       note_id, 
       subject_name, 
       count(subject_name collate utf8mb4_bin) over (partition by user_id, subject_name collate utf8mb4_bin) 
from notes_subject; 

如果window functions不成问题,也可以单独聚合,再加入主表。

DEMO

【讨论】:

  • 未知排序规则:出现“Latin1_General_CS_AS”错误。我在 ubuntu 中使用 MySql 8.0.21
  • @carljohnson 这是因为该解决方案是针对 SQL Server 的。立即尝试
  • @carljohnson 我不确定,因为我以前从未与人合作过
【解决方案2】:

通过selecting the group by column as a binary field发布另一个替代方案。

dbfiddle 用MYSQL 8.0 版本测试

SELECT cast(subject_name as binary) subject_name, COUNT(subject_name)  cnt
  FROM notes_subject 
 WHERE user_id=2 
GROUP BY cast(subject_name as binary)

【讨论】:

  • 但是如果我在 DB 中有很多行,那么我必须写 SELECT 10, 12, 13 ,14...
  • 不不,我只是将 CTE 用于演示目的。只需使用 SELECT cast(subject_name as binary) subject_name, COUNT(subject_name) cnt FROM notes_subject WHERE user_id=2 GROUP BY cast(subject_name as binary)
  • 检查 dbfiddle dbfiddle.uk/…
  • 它将subject_name的值作为0x434E而不是CN和0x636E而不是cn。
  • 我提供了 MYSQL 8.0 的小提琴链接及其工作。不知道为什么它会改变值,可能是因为数据库级别的任何参数设置。目前请忽略并使用窗口条款解决方案。如果我发现任何东西,我会检查并更新
【解决方案3】:

你可以简单地使用 Binary 来投射它。

SELECT count(*), CAST(subject_name as BINARY) AS lastname_cs 
FROM notes_subject where user_id=2 
GROUP BY CAST(subject_name as BINARY); 

【讨论】:

  • 什么是lastname_cs,我觉得是CPY帖子
  • 这是我在本地机器上创建的表。
猜你喜欢
  • 2015-06-20
  • 2015-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-31
  • 1970-01-01
  • 2017-03-07
相关资源
最近更新 更多