【发布时间】:2015-03-12 13:24:40
【问题描述】:
我有一张表,其中包含 37 列、各种类型、INT 和 VARCHARS 以及 2 个 LONGTEXT 列。客户端希望通过搜索来搜索表并找到匹配的行。
但是,我遇到了麻烦。这是我到目前为止所做的:
1) 我最初的想法是进行大量的 OR 查询 - 但是我需要提供大约 30 次搜索数据,这是大量重复,我确信在那里;比这更好的方法。
代码:
SELECT
MemberId,
MemNameTitle,
MemSName,
MemFName,
MemPostcode,
MemEmail
FROM
MemberData
WHERE
MemFName LIKE CONCAT('%',?,'%') OR
MemSName LIKE CONCAT('%',?,'%') OR
MemAddr LIKE CONCAT('%',?,'%') OR
MemPostcode LIKE CONCAT('%',?,'%') OR
MemEmail LIKE CONCAT('%',?,'%')
...etc...
等等。等等。这是一组庞大的 OR,而且非常笨拙。
2)我想我会尝试重新设计它以将所有列放在括号中,然后只询问一次查询,我在 SO 上看到了类似的代码,但不确定它是否正确工作,但它是灵感,至少:
SELECT
MemberId,
MemNameTitle,
MemSName,
MemFName,
MemPostcode,
MemEmail
FROM
MemberData
WHERE
(MemNameTitle OR
MemFName OR
MemSName OR
MemAddr OR
MemPostcode OR
MemEmail OR
MemSkype OR
MemLinkedIn OR
MemFacebook OR
MemEmailTwo ...etc...) LIKE CONCAT('%',?,'%')
GROUP BY
MemberId
此代码在没有明显错误的情况下执行,但由于它始终不返回任何结果而失败,如返回 0 个字段。我不明白为什么,从最初的角度来看,
3) 因此,通过对操作系统的一些研究,我发现使用 IN 关键字进行了重新排列,但从这里Is it possible to use LIKE and IN for a WHERE statment? 的先前问题来看,它似乎不起作用。
我想得到的是这样的:
SELECT
MemberId,
MemNameTitle,
MemSName,
MemFName,
MemPostcode,
MemEmail
FROM
MemberData
WHERE
MemNameTitle,
MemFName,
MemSName,
MemAddr,
MemPostcode,
MemEmail,
MemSkype,
MemLinkedIn,
...etc ...
MemFax,
MemberStatus,
CommitteeNotes,
SecondAddr,
SecondAddrPostcode IN (LIKE CONCAT('%',?,'%') )
这是粗略的语法,但我希望你能明白我想要得到的想法,我想使用 LIKE % % 子句在许多字段中搜索相同的值。字段是不同的 TEXT/VARCHAR 类型。
4) 然后我研究了 MySQL 全文搜索,但这很快就变得没用了,因为这仅适用于 TEXT 类型而不是 VARCHAR 类型搜索。我考虑在每次搜索之前将每个 VARCHAR 列更改为 TEXT 列,但认为这也是相对处理器密集型的,并且对于许多人必须要做的搜索来说似乎不合逻辑?
所以,我没有想法......你能帮我这样搜索吗?或者建议为什么我在尝试 2 中的代码总是返回零行?
干杯
附加工作:
5) 我一直在考虑重新排列 IN 子句语句并想出了这个:
SELECT *(lazy typing!) WHERE
CONCAT('%',?,'%') IN
(MemNameTitle,
MemFName,
MemSName,
MemAddr,
MemPostcode,
MemEmail,
MemSkype,
...etc...
CommitteeNotes,
SecondAddr,
SecondAddrPostcode)
GROUP BY MemberId
然而这会返回一个结果,但结果总是表的最后一行。这行不通。
解决方案 1:
来自 Ravinder,对所有字段使用 CONCAT_WS - 这适用于我的情况,虽然我认为 CONCAT 确实有些难看,但很好。
SELECT * FROM MemberData WHERE
CONCAT_WS('<*!*>',
MemNameTitle, MemFName, MemSName,
MemAddr, MemPostcode, MemEmail,
MemSkype, MemLinkedIn,
...etc...
MemberStatus, CommitteeNotes, SecondAddr,
SecondAddrPostcode)
LIKE CONCAT('%',?,'%')
GROUP BY MemberId ";
该表最终将有几千行,我有点担心,因为此查询将为每次搜索的表上的每一行连接 24 列,这很容易变得非常昂贵和低效(即慢) ,所以如果有人有任何方法
i) 搜索没有 CONCAT 列或
ii) 使这个解决方案更快/更高效
请分享!!
【问题讨论】:
-
@Borr 感谢格式化 :)