SQL SELECT 名称 LIKE $name 但不完全相同的名称两次
Posted
技术标签:
【中文标题】SQL SELECT 名称 LIKE $name 但不完全相同的名称两次【英文标题】:SQL SELECT names LIKE $name but not exact same name twice 【发布时间】:2013-09-13 01:47:08 【问题描述】:我正在使用此 SQL 查询来遍历表并搜索客户名称并返回该行的 id 和日期列:
SELECT custName, date, id FROM booking
WHERE custName LIKE '%$s'
OR custName LIKE '$s%'
($s 是一个 php 变量)
如果我正在寻找 John Dorian,我可以输入 $s 作为名字 John 或姓氏 Dorian,我的函数会找到他。我的问题是 John Dorian 可能出现在多行中,如果是这种情况,我希望查询只返回最近的行(使用日期列来解决这个问题)。
IE 如果我的表看起来像这样并且 $s = John:
(custName, date, id)
John Dorian - 2013/01/01 - 1
John Doe - 2013/01/02 - 2
John Dorian - 2013/01/10 - 3
我希望我的查询返回
John Doe - 2013/01/02 - 2
John Dorian - 2013/01/10 - 3
【问题讨论】:
你应该选择一个正确的答案。 【参考方案1】:怎么样:
SELECT custName, date, id
FROM booking b
INNER JOIN
(
SELECT max(date) MaxDate, custName
FROM booking
WHERE custName LIKE '%$s%'
GROUP BY custName
) bm
ON b.custName = bm.custName
AND b.date = bm.maxDate
WHERE custName LIKE '%$s%'
ORDER BY b.date DESC
【讨论】:
需要聚合非组列【参考方案2】:1) 您可以使用DISTINCT
或GROUP BY
轻松搜索并获取每位客户的一行:
SELECT DISTINCT custName
FROM booking
WHERE custName LIKE '%$s' OR custName LIKE '$s%';
或
SELECT custName
FROM booking
WHERE custName LIKE '%$s' OR custName LIKE '$s%'
GROUP BY custName;
2) 您可以通过将聚合函数(即MAX
)与GROUP BY
耦合来获得最大日期
SELECT custName, MAX(date) as date
FROM booking
WHERE custName LIKE '%$s' OR custName LIKE '$s%'
GROUP BY custName;
3) 最后,您可以通过将结果连接回原始表来获得完整的表行:
SELECT b.custName, b.date, b.id
FROM booking AS b
INNER JOIN
(SELECT custName, MAX(date) AS maxDate
FROM booking
WHERE custName LIKE '%$s' OR custName LIKE '$s%'
GROUP BY custName
) AS gb
ON b.custName = gb.custName AND b.date = gb.maxDate;
或(可能更慢):
SELECT b.custName, b.date, b.id
FROM booking AS b
INNER JOIN
(SELECT custName, MAX(date) AS maxDate
FROM booking
GROUP BY custName
) AS gb
ON b.custName = gb.custName AND b.date = gb.maxDate
WHERE b.custName LIKE '%$s' OR b.custName LIKE '$s%';
附言
以下内容可能看起来很有希望,有时甚至可能给出正确的结果,但不能保证有效。
SELECT *
FROM (
SELECT custName, date, id
FROM booking
WHERE b.custName LIKE '%$s' OR b.custName LIKE '$s%'
ORDER BY date DESC
) AS t
GROUP BY custNAME;
很遗憾,您不能依靠GROUP BY
来维持提供的订单。
编辑另见
mysql order by before group by How can I SELECT rows with MAX(Column value), DISTINCT by another column in SQL? http://ftp.nchu.edu.tw/MySQL/tech-resources/articles/debunking-group-by-myths.html【讨论】:
【参考方案3】:我认为您需要在 custName 列上有一个不同的值。虽然我自己没有尝试过,但我认为 BadWolf 的答案会返回名为“John Dorian”的两行:
SELECT distinct(custName), date, id FROM booking WHERE
custname LIKE '%$s%'
GROUP BY custName, date, id
ORDER BY date DESC
【讨论】:
这没有多大意义。如果您GROUP BY
全部三个值(custName、日期和 id),那么您可能根本不使用 GROUP。
我喜欢这个,因为它比其他解决方案简单得多。我只按 custName 分组(按所有三个分组没有返回任何结果)。同样在此刻,我只得到最旧的行,而不是最新的。我尝试按日期 asc/desc 排序,但无济于事。稍后会尝试更多。
它可能更简单,但实际上并不能正常工作。 GROUP BY
在未提供聚合函数时任意选择行值。在此查询中,GROUP BY
发生在 ORDER BY
之前,因此在对行进行排序之前已经(任意)选择了 date
和 id
值。但是,即使您首先 将结果排序到内部SELECT
,然后将结果分组到外部“SELECT”中,也不能保证有效。请参阅我的解决方案和this article。【参考方案4】:
乍一看,我以为这是一个简单的问题,但我错了。
我只能通过follow语句来解决。
select * from
(SELECT custName, date, id FROM booking
WHERE custName LIKE '%$s' OR
custName LIKE '$s%' order by date desc) as t
group by (t.custName) order by date ;
它可能有其他更好的解决方案。
【讨论】:
以上是关于SQL SELECT 名称 LIKE $name 但不完全相同的名称两次的主要内容,如果未能解决你的问题,请参考以下文章