Mysql 分组有问题吗?
然而,现在当我试图从第二个表(存储更多信息)中获取一些信息时,我遇到了一些问题 我的桌子如下 使用者 侧面图 我的SQL如下(基于上一个线程) 问题是我的输出显示如下Mysql 分组有问题吗?,mysql,Mysql,然而,现在当我试图从第二个表(存储更多信息)中获取一些信息时,我遇到了一些问题 我的桌子如下 使用者 侧面图 我的SQL如下(基于上一个线程) 问题是我的输出显示如下 +----+----------------------+-------------+-------+ | id | username | facebook | steam | +----+----------------------+-------------+-------+ | 1 | Use
+----+----------------------+-------------+-------+
| id | username | facebook | steam |
+----+----------------------+-------------+-------+
| 1 | Username1 | 10049424151 | 11 |
| 2 | Username2 | 10051277183 | 55 |
| 3 | LongUsername | 10051281183 | 751 |
| 4 | Username4 | 10051215770 | 4444 |
| 5 | Username5 | 10049424151 | 11 |
| 6 | Username6 | 10049424151 | 55 |
+----+----------------------+-------------+-------+
我不知道,你到底想对输出做什么,但你不能像这样对信息进行分组。MySQL并不是一种真正的经典编程语言,它更像是集合数学的强大工具。因此,如果您想根据两个或多个表之间的相关性获取信息,首先要编写一条select语句,其中包含要处理的原始数据,如下所示:
SELECT * FROM users u INNER JOIN profile p ON p.id=u.id
GROUP BY u.id;
WHERE p.id=u.id AND ( FIND_IN_SET('7',secondary_groups) OR primary_group = 7 )
-- ^ ^
现在使用WHERE语句选择相关数据:
SELECT * FROM users u INNER JOIN profile p ON p.id=u.id WHERE
FIND_IN_SET( '7', secondary_groups ) OR primary_group = 7
GROUP BY u.id;
现在您应该可以看到分组的联接表概要文件和用户,并可以开始挖掘数据。例如,如果您想对这些组中的项目进行计数,只需在SELECT中添加count函数,依此类推。
调试SQL时,我强烈建议执行以下步骤:
1.)首先,您应该写下数据之间的所有相关关系,表之间的所有外键,以便知道您的选择是否完全确定。现在可以开始从左到右连接表
2.)在模型数据库上尝试少量查询。然后,您将看到哪些选择正确,哪些不符合您的预期。我猜问题在于
配置文件
包含7个主组的行与所有用户
行匹配。通过
删除分组,您将能够更好地看到发生了什么
但这只是一个猜测。现在还不清楚你想要实现什么
我怀疑你被和和或的优先顺序绊倒了。(与或
运算符相比,和
运算符的优先级更高。这意味着将在或
之前对和
进行求值)
快速修复方法是只添加一些参数,以覆盖默认的操作顺序。大概是这样的:
SELECT * FROM users u INNER JOIN profile p ON p.id=u.id
GROUP BY u.id;
WHERE p.id=u.id AND ( FIND_IN_SET('7',secondary_groups) OR primary_group = 7 )
-- ^ ^
parens将导致对或操作进行求值(TRUE、FALSE或NULL),然后在和中对其结果进行求值
没有帕伦夫妇,就好像帕伦夫妇在这里一样:
WHERE ( p.id=u.id AND FIND_IN_SET('7',secondary_groups) ) OR primary_group = 7
-- ^ ^
首先评估和
条件,然后由或
对其结果进行操作。这就是导致配置文件中带有7的行与用户中具有不同id值的行相匹配的原因
关于风格的几点建议:
- 避免使用老式的逗号运算符进行连接操作,并使用较新的
join
语法
- 将连接谓词(条件)放在
ON
子句中,将其他筛选条件放在WHERE
子句中
- 限定所有列引用
例如:
SELECT u.id
, u.username
, p.id
, p.facebook
, p.steam
FROM users u
JOIN profile p
ON p.id = u.id
WHERE u.primary_group = 7
OR FIND_IN_SET('7',u.secondary_groups)
ORDER BY u.id
如果我们想“折叠”行,我们只需要一个GROUPBY
子句。如果id
列在users
和profile
表中都是唯一的,则不需要按u.id
分组。如果希望按特定顺序返回行,我们可以添加一个ORDER BY
子句。我认为@SIDU在注释中有这样的说法:您遇到了布尔运算顺序问题。另见
例如:
SELECT 0 AND 0 OR 1 AS test;
+------+
| test |
+------+
| 1 |
+------+
当同时使用和和或执行复杂语句时,请使用括号。操作员顺序问题导致您执行了一个意外的外部联接,该联接正被您的GROUP by
掩盖。该语句不需要分组依据
虽然我个人并不喜欢@spencer7593在他的回答中所建议的风格(使用内部连接
,等等),但它确实有一个优点,即对于SQL新手来说,可以及早防止或识别错误,这是一个需要考虑的问题。你的输出有什么问题?请告诉我们你期望的输出是不确定的值,因为你没有在组中的列上有聚合函数。用户名4应该有id 5您没有解释您试图做什么,没有解释任何类型的问题,也没有问任何问题。(不,分组问题?不是问题。这是一个无用的标题,你用在你的文章中。)这个网站是关于你正在经历的明确问题的具体问题。这些东西你都没有提供。请完成并仔细阅读这些页面,特别是,然后回到这里并阅读您的帖子。一定要提高标题的描述性;如果id
在用户
和配置文件
表中都是唯一的,则不必使用group by
子句。这个答案中的两个查询都避免了(因此似乎修复了)OP查询遇到的问题,而没有提到实际问题是什么。。。和
和或
运算符的意外(但有很好的文档记录)“优先顺序”。
SELECT 0 AND 0 OR 1 AS test;
+------+
| test |
+------+
| 1 |
+------+