我知道我可以编写一个查询,它将返回给定列中包含任意数量值的所有行,如下所示:
Select * from tbl where my_col in (val1, val2, val3,... valn)
但是,例如val1
可以出现在my_col
中的任何位置,其数据类型为varchar(300),我可能会改写:
select * from tbl where my_col LIKE '%val1%'
有没有办法梳理这两种技术。我需要搜索可能出现在列的自由格式文本中的任何位置的30个可能值。
以下列方式组合这两个语句似乎不起作用:
select * from tbl where my_col LIKE ('%val1%', '%val2%', 'val3%',....)
select * from tbl where my_col in ('%val1%', '%val2%', 'val3%',....)
答案 0 :(得分:25)
select * from tbl
where my_col like '%val1%' or my_col like'%val2%' or my_col like '%val3%', ...
但要注意,这可能会很慢......或者,您可以将所有可接受的值(包括%
符号)插入表中并半连接该表:
select * from tbl
where exists (select 1 from all_likes where tbl.my_col like all_likes.value)
对于真正的全文搜索,您可能需要查看Oracle Text:
http://www.oracle.com/technetwork/database/enterprise-edition/index-098492.html
答案 1 :(得分:6)
不,你不能这样做。 IN子句中的值必须是完全匹配。你可以这样修改选择:
SELECT *
FROM tbl
WHERE my_col LIKE %val1%
OR my_col LIKE %val2%
OR my_col LIKE %val3%
...
如果val1,val2,val3 ......足够相似,您可以在REGEXP_LIKE运算符中使用正则表达式。
答案 2 :(得分:4)
在 Oracle 中,您可以按如下方式使用 regexp_like:
select *
from table_name
where regexp_like (name, '^(value-1|value-2|value-3....)');
插入符号 (^) 操作符表示行首字符 & 管道 (|) 运算符表示 OR 运算。
答案 3 :(得分:3)
REGEXP_LIKE
将执行不区分大小写的正则表达式搜索。
select * from Users where Regexp_Like (User_Name, 'karl|anders|leif','i')
这将作为全表扫描执行 - 就像LIKE or
解决方案一样,如果表格不小,性能将真的不好。如果它根本不经常使用,那可能没问题。
如果您需要某种性能,则需要 Oracle Text (或某些外部索引器)。
要使用Oracle Text获取子字符串索引,您需要一个CONTEXT索引。它有点牵扯,因为它是使用大量智能索引大型文档和文本。如果您有特殊需求,例如子串搜索数字和所有单词(包括""""" a",空格等),您需要创建自定义词法分析器以删除一些聪明的东西...
如果插入大量数据,Oracle Text不会让事情变得更快,特别是如果您需要在事务中更新索引而不是定期更新。
答案 4 :(得分:1)
是的,您可以使用此查询:
SELECT * FROM RandomTable rt
WHERE EXISTS (select 1 from table(sys.dbms_debug_vc2coll(//INSERT STRINGS SEPARATED BY COMMA HERE)) as MemoryTable mt where rt.name like mt.column_value);
为什么我的查询比接受的答案更好:您不需要CREATE TABLE
权限来运行它。这可以仅使用SELECT
权限执行。
答案 5 :(得分:1)
添加@Lukas Eder的答案。
避免创建表和插入值的改进
(我们可以使用select from dual
和unpivot
来实现相同的结果"即时"):
with all_likes as
(select * from
(select '%val1%' like_1, '%val2%' like_2, '%val3%' like_3, '%val4%' as like_4, '%val5%' as like_5 from dual)
unpivot (
united_columns for subquery_column in ("LIKE_1", "LIKE_2", "LIKE_3", "LIKE_4", "LIKE_5"))
)
select * from tbl
where exists (select 1 from all_likes where tbl.my_col like all_likes.united_columns)
答案 6 :(得分:1)
我更喜欢这个
WHERE CASE WHEN my_col LIKE '%val1%' THEN 1
WHEN my_col LIKE '%val2%' THEN 1
WHEN my_col LIKE '%val3%' THEN 1
ELSE 0
END = 1
我并不是说它是最佳的,但它有效,而且很容易理解。我的大多数查询都是adhoc一次使用,所以性能通常不是我的问题。
答案 7 :(得分:1)
这个非常快:
select * from listofvalue l
inner join tbl on tbl.mycol like '%' || l.value || '%'
答案 8 :(得分:1)
您可以将值放入ODCIVARCHAR2LIST,然后将其作为常规表加入。
select tabl1.* FROM tabl1 LEFT JOIN
(select column_value txt from table(sys.ODCIVARCHAR2LIST
('%val1%','%val2%','%val3%')
)) Vals ON tabl1.column LIKE Vals.txt WHERE Vals.txt IS NOT NULL
答案 9 :(得分:0)
select * from tbl
where exists (select 1 from all_likes where all_likes.value = substr(tbl.my_col,0, length(tbl.my_col)))
答案 10 :(得分:0)
您不需要https://stackoverflow.com/a/6074261/802058 中提到的集合类型。只需使用子查询:
import kotlinx.serialization.*
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.*
@Serializable(with = PacketSerializer::class)
data class Packet(val dataType: String, val payload: Any)
object PacketSerializer : KSerializer<Packet> {
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("Packet") {
element("dataType", serialDescriptor<String>())
element("payload", buildClassSerialDescriptor("Any"))
}
@Suppress("UNCHECKED_CAST")
private val dataTypeSerializers: Map<String, KSerializer<Any>> =
mapOf(
"String" to serializer<String>(),
"Int" to serializer<Int>(),
//list them all
).mapValues { (_, v) -> v as KSerializer<Any> }
private fun getPayloadSerializer(dataType: String): KSerializer<Any> = dataTypeSerializers[dataType]
?: throw SerializationException("Serializer for class $dataType is not registered in PacketSerializer")
override fun serialize(encoder: Encoder, value: Packet) {
encoder.encodeStructure(descriptor) {
encodeStringElement(descriptor, 0, value.dataType)
encodeSerializableElement(descriptor, 1, getPayloadSerializer(value.dataType), value.payload)
}
}
@ExperimentalSerializationApi
override fun deserialize(decoder: Decoder): Packet = decoder.decodeStructure(descriptor) {
if (decodeSequentially()) {
val dataType = decodeStringElement(descriptor, 0)
val payload = decodeSerializableElement(descriptor, 1, getPayloadSerializer(dataType))
Packet(dataType, payload)
} else {
require(decodeElementIndex(descriptor) == 0) { "dataType field should precede payload field" }
val dataType = decodeStringElement(descriptor, 0)
val payload = when (val index = decodeElementIndex(descriptor)) {
1 -> decodeSerializableElement(descriptor, 1, getPayloadSerializer(dataType))
CompositeDecoder.DECODE_DONE -> throw SerializationException("payload field is missing")
else -> error("Unexpected index: $index")
}
Packet(dataType, payload)
}
}
}