如何在同一SQL语句中使用SELECT DISTINCT和CONCAT

12

所以我正在将这个SQL的结果输入到一个数组中。该数组后来成为一个在输入时操作的文本框的建议列表。我希望它只返回每个姓名1次,即使该人有多个约会。目前,它返回该名称的所有约会,因此如果“Brad Robins”有5个约会,并且我开始输入“Brad”,则建议中会显示“Brad Robins” 5次,而不是只显示一次。

$sql = "SELECT DISTINCT CONCAT(clients.studentFirstName, ' ', clients.studentLastName) AS name, appointments.location, appointments.subLocation, appointments.appointmentAddress1, appointments.appointmentAddress2, appointments.appointmentCity, appointments.appointmentState, appointments.appointmentZip, appointments.startTime, appointments.endTime, appointments.date, clients.school
                    FROM appointments JOIN clients
                    ON appointments.clientID = clients.clientID
                    WHERE CONCAT(clients.studentFirstName, ' ', clients.studentLastName) = '".$roommate."' AND clients.school = '".$school."';";

在我看来,DISTINCT和CONCAT似乎不能很好地协同工作。


如果此查询的唯一目的是返回一个名称列表以向用户提供建议,并且您实际上没有在程序的最终输出中使用预约表... 那么为什么首先要连接它? - mikurski
我稍后会使用其他信息,但将其分离并执行两个查询非常容易,只留下第一个名称。 - radleybobins
7个回答

6
不要使用DISTINCT,使用group by:
$sql = "SELECT CONCAT(clients.studentFirstName, ' ', clients.studentLastName) AS name, appointments.location, appointments.subLocation, appointments.appointmentAddress1, appointments.appointmentAddress2, appointments.appointmentCity, appointments.appointmentState, appointments.appointmentZip, appointments.startTime, appointments.endTime, appointments.date, clients.school
                FROM appointments JOIN clients
                ON appointments.clientID = clients.clientID
                WHERE CONCAT(clients.studentFirstName, ' ', clients.studentLastName) = '".$roommate."' AND clients.school = '".$school."' group by CONCAT(clients.studentFirstName, ' ', clients.studentLastName);";

另外要注意,如果 $school 和 $roomate 可以在外部访问时,要小心防范 XSS 攻击。

非常好的解决方案!我已经根据前两个答案将其改为了两个查询,但下次一定会记住这个! - radleybobins

6
问题在于其它字段;DISTINCT 应用于整个结果。可能最好的做法是分别查询或填充两个不同的数组;如果您按名称排序,可以通过仅在名称更改时将内容复制到目标数组中来删除重复项。

1
这两个答案都是正确的,并且同时提交。很抱歉我不能将它们都标记为正确。感谢您的时间! - radleybobins

4

Distinct适用于整行的所有列,而不仅仅是名称部分...因此,如果预约在不同日期/时间、地点等方面有所不同,它们都会被列出。如果你只想显示名字部分,则剥离其他内容。在选择一个人之后查询可用的预约。


1

你可以使用

group by name

最后,这会导致查询仅返回每个名称中的一个,但是在客户有多个约会的情况下,您无法预测将返回哪些约会结果,因此查询变得不太有用。

正如其他人指出的那样,您应该在选择客户后获取约会列表。


0
SELECT DISTINCT MD5(CONCAT(clients.studentFirstName, ' ', clients.studentLastName)) as id, appointments.location, appointments.subLocation, ...

0
select colA||' - '||colB
from table1
where colA like 'beer%'
group by colA||' - '||colB
order by colA||' - '||colB
;

-2

从...中选择不同的concat(...)返回


2
它似乎与作者的问题没有太大区别。如果您能澄清作者代码中的问题会更好。 - bashnesnos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接