2017-02-10 4 views
0

私は数多くの質問を見つけましたが、この問題は解決できません。文字列+特定のint列の比較を含むMysqlの選択行

私のテーブルには、3つの列が整数値で満たされ、3つの列に文字列値があります。私はいくつかの行を持っています。

表の構成例:

INT_1 | INT_2 | INT_3 | VALUE1 | VALUE2 | VALUE3 
    33 | 25 | 10 | "nice"| "hello"| "goodbye" 
    --------------------------------------------------- 
    10 | 15 | 28 | "dice"| "hay" | "bird" 

私は値列に基づいて行を選択するために使用ストリングを有します。私が選択したいのは、文字列が "llo"の場合のインクルードです。少なくともの値(VALUE、VALUE2、VALUE3)のいずれかに "llo"が含まれていますVALUE2の "hello"など)。

しかし、文字列が "ice"の場合のように、2つの異なる行に文字列を含むVALUE列がある場合、その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+""; 
  • を私は「+文字列+」のような値を持っている場合、文字列を含むかどうかを確認するために、「LIKE」が含まれるべきかわかりません。
  • VALUEに文字列が含まれている行が複数ある場合、特定のINT列と特定のVALUE列を比較する方法がわかりません。
+0

本当にMySQLを使用していますか? –

答えて

1

最初にUNION ALLを使用してテーブルを正規化します。つまり、すべての行を3つに分割する必要があります。各グループに1つ(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

今サブクエリに入れてWHERE v LIKE '%ice%'を使用してv欄にご文字列を検索します。

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

最終ステップ - ORDER BY i DESC LIMIT 1を用いiに最高値を持つ行をピック:

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

あなたはWHEREの代わりにHAVING句を使用する場合は、サブクエリを使用する必要はありませんので、クエリは、短くすることができます。しかし、必要がないかもしれない2つの列(iv)が得られます。一方、あなたが必要とする唯一の列であるかもしれません。

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 
+0

しばらくして、それが働いた。ありがとうございました。 – DigitalEvolution

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; 
+0

ありがとうございます。まだ学習しています... – DigitalEvolution

+0

これはあなたのために機能しますか? –

+0

試してみませんか?私は上記の答えをした – DigitalEvolution