我发现了很多与我有关的问题,但仍然无法解决这个问题。
在我的表中有3列填充整数值,3列填充字符串值。我有好几行。
表结构示例:
INT_1 | INT_2 | INT_3 | VALUE1 | VALUE2 | VALUE3
33 | 25 | 10 | "nice"| "hello"| "goodbye"
---------------------------------------------------
10 | 15 | 28 | "dice"| "hay" | "bird"
我有一个字符串,用于根据VALUE列选择行。我想要选择它的方式是包含,这意味着如果字符串是“llo”我应该得到至少其中一个值(VALUE,VALUE2,VALUE3)包含“llo”的行(会在VALUE2中选择“hello”行,例如)。
但是,如果两个不同的行具有包含字符串的VALUE列(如示例中的字符串是“ice”),我想检索与该VALUE关联的INT列更高的行。在示例中,因为字符串与VALUE1进行比较,我应该将上一列的INT_1与下一列的INT_1进行比较,并检索INT_1更高的行。 (INT_1 - > VALUE1,INT_2 - > VALUE2,INT_3 - > VALUE3)。
唔不多但我自己也能想到这个:
SELECT * FROM my_table WHERE VALUE1 = "+string+" OR VALUE2= "+string+" OR VALUE3= "+string+"";
答案 0 :(得分:1)
首先使用UNION ALL
规范化您的表格。这意味着每行必须分成三行。每组一个(INT_1 VALUE1
,INT_2 VALUE2
,INT_3 VALUE3
)。由于您没有显式主键,因此需要包括所有列以标识源行。
select t.*, 1 as position, INT_1 as i, VALUE1 as v from my_table t
union all
select t.*, 2 as position, INT_2 as i, VALUE2 as v from my_table t
union all
select t.*, 3 as position, INT_3 as i, VALUE3 as v from my_table t
结果:
| INT_1 | INT_2 | INT_3 | VALUE1 | VALUE2 | VALUE3 | position | i | v |
|-------|-------|-------|--------|--------|---------|----------|----|---------|
| 33 | 25 | 10 | nice | hello | goodbye | 1 | 33 | nice |
| 10 | 15 | 28 | dice | hay | bird | 1 | 10 | dice |
| 33 | 25 | 10 | nice | hello | goodbye | 2 | 25 | hello |
| 10 | 15 | 28 | dice | hay | bird | 2 | 15 | hay |
| 33 | 25 | 10 | nice | hello | goodbye | 3 | 10 | goodbye |
| 10 | 15 | 28 | dice | hay | bird | 3 | 28 | bird |
http://sqlfiddle.com/#!9/9086d5/1
现在将其放入子查询中,并使用v
在WHERE v LIKE '%ice%'
列中搜索您的字符串。
select *
from (
select t.*, 1 as position, INT_1 as i, VALUE1 as v from my_table t
union all
select t.*, 2 as position, INT_2 as i, VALUE2 as v from my_table t
union all
select t.*, 3 as position, INT_3 as i, VALUE3 as v from my_table t
) n
where v like '%ice%'
结果:
| INT_1 | INT_2 | INT_3 | VALUE1 | VALUE2 | VALUE3 | position | i | v |
|-------|-------|-------|--------|--------|---------|----------|----|------|
| 33 | 25 | 10 | nice | hello | goodbye | 1 | 33 | nice |
| 10 | 15 | 28 | dice | hay | bird | 1 | 10 | dice |
http://sqlfiddle.com/#!9/9086d5/4
最后一步 - 使用i
选择ORDER BY i DESC LIMIT 1
中值最高的行:
select `INT_1`, `INT_2`, `INT_3`, `VALUE1`, `VALUE2`, `VALUE3`
from (
select t.*, 1 as position, INT_1 as i, VALUE1 as v from my_table t
union all
select t.*, 2 as position, INT_2 as i, VALUE2 as v from my_table t
union all
select t.*, 3 as position, INT_3 as i, VALUE3 as v from my_table t
) n
where v like '%ice%'
order by i desc
limit 1
结果:
| INT_1 | INT_2 | INT_3 | VALUE1 | VALUE2 | VALUE3 |
|-------|-------|-------|--------|--------|---------|
| 33 | 25 | 10 | nice | hello | goodbye |
http://sqlfiddle.com/#!9/9086d5/5
如果使用HAVING
子句而不是WHERE
,则查询可以更短,因此您不需要使用子查询。但是,您可能会得到两列(i
和v
),您可能不需要这些列。另一方面,它们可能是您需要的唯一列。
select t.*, INT_1 as i, VALUE1 as v from my_table t union all
select t.*, INT_2 as i, VALUE2 as v from my_table t union all
select t.*, INT_3 as i, VALUE3 as v from my_table t
having v like '%ice%'
order by i desc
limit 1
还有一项修改可能会稍微提高性能:
select t.*, INT_1 as i from my_table t where VALUE1 like '%ice%' union all
select t.*, INT_2 as i from my_table t where VALUE2 like '%ice%' union all
select t.*, INT_3 as i from my_table t where VALUE3 like '%ice%'
order by i desc
limit 1
答案 1 :(得分:1)
这是一个糟糕的数据结构。但这是一种方法吗?
SELECT t.*
FROM my_table t
WHERE VALUE1 LIKE '%string%' OR VALUE2 LIKE '%string%' OR VALUE3 LIKE '%string%'
ORDER BY greatest( (case when VALUE1 LIKE '%string%' then int_1 else -1 end),
(case when VALUE1 LIKE '%string%' then int_2 else -1 end),
(case when VALUE1 LIKE '%string%' then int_3 else -1 end) ) desc
LIMIT 1;