我在linux中使用mysql版本5.7.13
当我运行存储过程时,我收到以下错误
ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause
and contains nonaggregated column 'medigurus.pp.physicianid' which is not
functionally dependent on columns in GROUP BY clause; this is
incompatible with sql_mode=only_full_group_by
我的程序是
DELIMITER $$ DROP PROCEDURE IF EXISTS medigurus.getPatientDoctors$$ CREATE
DEFINER=root@localhost PROCEDURE getPatientDoctors(IN patientid INT(10))
BEGIN SELECT pp.physicianid, d.physiciantypeid, p.firstname, p.lastname,
p.dob, p.mobile, p.officephone, p.address1, p.address2, p.city, p.stateid,
p.cid, p.zip,p.speciality, p.about, p.imgid FROM patientphysicians pp INNER
JOIN physician p ON pp.physicianid = p.physicianid INNER JOIN
getpatientdoctorsview AS d ON d.patientid=pp.patientid WHERE pp.patientid
= patientid GROUP BY p.physicianid; END$$ DELIMITER ;
并且查看
DELIMITER $$
DROP VIEW IF EXISTS `medigurus`.`getpatientdoctorsview`$$
CREATE ALGORITHM=UNDEFINED
DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `getpatientdoctorsview` AS
select `pp`.`physicianid` AS `physicianid`,`pp`.`patientid` AS
`patientid`,group_concat(`pp`.`physiciantypeid` separator ',') AS
`physiciantypeid`
from `patientphysicians` `pp` group by `pp`.`patientid`$$
DELIMITER ;
如何解决错误..
答案 0 :(得分:1)
快速解决方案是将聚合函数应用于medigurus.pp.physicianid
,如下所示:
select ... min(medigurus.pp.physicianid) as physicianid, ...
错误消息的原因是medigurus.pp.physicianid
不明确,因为每个组可能有多个值,而SQL引擎需要选择一个。没有这个设置(限制),它只会占用它遇到的第一个,但是这种行为不符合SQL标准。
但是,通过指明要返回的这些值中的哪一个(例如,通过min
),您可以解决问题。
或者,尽管没有建议,但您可以通过清除此选项返回到MySql的旧行为:
SET sql_mode = ''
正如您在更新问题时提供的实际SQL,我在此添加了我的观察结果:
视图的select
按 patientid 对结果进行分组,以便汇总相关医生的类型。但是,您也选择 physicianid :这没有什么意义,因为一般情况下您可能有几个不同的医生与一个患者相关联,因此其价值不是单数。您应该省略该字段 - 或者如果您确实需要每位患者一位医生,您应该问自己一个问题:哪一个,如果有多个?在这里,我建议省略它:
select patientid AS patientid,
group_concat(physiciantypeid separator ',') AS physiciantypeid
from patientphysicians
group by patientid
其次,程序的SQL也需要修正。您似乎想列出与某个特定患者相关的所有医生的详细信息。为此目的,加入视图是没有意义的,因为视图仅返回患者的一条记录,并将医生类型聚合为逗号分隔列表。这对于您在过程中使用的SQL没有用,您希望为每位医生提供单独的记录。因此,从中移除视图,然后返回每位医生的医生类型。
除此之外,您应该使用与select
列表中相同的 physicianid 进行分组。不要从 p 中的 physicianid 中的select
子句中选择 pp 中的 doctorid >
以下是建议的更新:
SELECT p.physicianid,
p.physiciantypeid,
p.firstname,
p.lastname,
p.dob,
p.mobile,
p.officephone,
p.address1,
p.address2,
p.city,
p.stateid,
p.cid,
p.zip,
p.speciality,
p.about,
p.imgid
FROM patientphysicians pp
INNER JOIN physician p
ON pp.physicianid = p.physicianid
WHERE pp.patientid = patientid /* the argument */
GROUP BY p.physicianid
请注意,在应用适当的缩进时,更有助于理解代码。