mysql - 未捕获的 mysqli_sql_exception:子查询返回多于 1 行
问题描述
我有两张桌子,一张有名字和电话号码,第二张有电话
addressbook name(VARCHAR) number(VARCHAR)
calls date(DATE) number(VARCHAR) name(VARCHAR)
我想用地址簿中的条目更新调用表中的名称列
UPDATE calls
SET name = ( SELECT name FROM addressbook WHERE number = calls.number )
WHERE DATE = "2020.01.01"
ORDER BY DATE
我得到Uncaught mysqli_sql_exception: Subquery return more than 1 row但地址簿中没有双引号我检查了几次。
解决方案
您的更新语句可能失败的唯一方法
子查询返回超过 1 行
是如果至少有calls
一行的数字在 中出现多次addressbook
。您可以使用以下查询找到它们:
select number, count(*)
from addressbook
group by number
having count(*) > 1;
假设您有这两行addressbook
:
name number
------ ------
fred 123
barney 123
假设这是行calls
:
date name number
---------- ---- ------
2020.01.01 null 123
当您执行 Stefano 的更新语句时,限制子句不是确定性的,因为子查询中没有关联order by
的子句。也没有任何共同的属性calls
,addressbook
这会使它有意义。关于更新的order by
条款是无关紧要的。因此,您不能保证将哪个名称分配给该calls
行。这就是我在对 Stefano 的回答发表评论时试图表达的观点。
如果系统的设计是允许多个人在一段时间内拥有一个号码(他们当然是这样),那么您的架构是不完整的。如果这是真的,那么addressbook
需要号码所有者的生效日期。
如果系统的设计不允许随着时间的推移多个人拥有一个号码,那么您必须删除重复的行。
无论哪种情况,您都需要做两件事:
- 采用声明性参照完整性约束,这样您就不会再次发生冲突
- 停止更新
calls
:插入(不更新)名称或完全删除列
如果我要实现电话系统的表格,我会从以下内容开始:
create table PERSON (
PERSON_ID integer not null primary key,
NAME varchar(100) not null /*lots of other columns*/);
create table PERSON_PHONE (
PERSON_PHONE_ID integer not null primary key,
PERSON_ID integer not null,
PHONE_NUM varchar(30) not null,
CONTRACTED date not null, /*lots of other columns*/
unique (PERSON_ID, PHONE_NUM, CONTRACTED),
foreign key (PERSON_ID) references PERSON(PERSON_ID));
create table PHONE_CALL (
START_DATE date not null,
END_DATE date not null,
PERSON_PHONE_ID integer not null,
primary key (PERSON_PHONE_ID, START_DATE),
foreign key (PERSON_PHONE_ID) references PERSON_PHONE(PERSON_PHONE_ID));
确实,有时,为了使用更少的资源更快地完成查询,人们有时会对模式进行非规范化以减少原本需要的连接操作的数量。非规范化需要仔细考虑。
推荐阅读
- c - 从C中的字符串中删除出现的数组
- aws-kms - 微软的 KMS 在功能上是否与亚马逊的 KMS 相同?
- mysql - MySQL - 多行触发器
- pycharm - 使用 attrs 对子类进行 Pycharm 类型提示
- python - QTableView中的单选行激活列编辑
- reactjs - 基于 JSON 文件加载图片 react
- ruby - Checking if test failed and giving console output accordingly
- javascript - 多次按下按钮问题
- php - Laravel 5如何检查用户是否存在于我的另一个表中
- c - fscanf Issue-Not able to extract string from file