2015-08-14 5 views
1

Так что я не знаю, возможно ли это, но я хотел бы вернуть имя столбца, имеющего значение шкафа для моего запроса.имя возвращаемого столбца с самым близким значением

Так что это мой стол:

-------------------------- 
| ID | D1 | D2 | D3 | D4 | 
-------------------------- 
| 1 | 0 | 10 | 22 | 50 | 
-------------------------- 

Я хотел бы сделать запрос, где я ищу в D1 Д4 для ближайшего значения 20, в этом случае D3

Тогда я как вернуть D3 и значение в нем.

Так что мой ответ должен быть:

------ 
| D3 | 
------ 
| 22 | 
------ 

Является ли это любым возможным способом?

+2

Можете ли вы изменить свой дизайн стола? Это не нормируется –

+0

Что делать, если несколько значений наиболее близки? –

+0

не может изменить таблицу, это то, с чем мне нужно работать :( – BonifatiusK

ответ

5

Не легко. Поскольку у вас есть те, как разные поля в одной и той же записи, вы должны будете использовать очень уродливые запросы:

SELECT source, val, ABS(20 - val) AS diff 
FROM (
    SELECT 'd1' AS source, d1 AS val FROM foo 
    UNION ALL 
    SELECT 'd2', d2 FROM foo 
    UNION ALL 
    SELECT 'd3', d3 FROM foo 
    UNION ALL 
    SELECT 'd4', d4 FROM foo 
) AS child 
ORDER BY diff DESC 
LIMIT 1 

Вы должны normalize таблицу, which'd полностью устранить все union бизнеса и оставить только внешний родительский запрос.

+0

не может нормализовать таблицу. Это выглядит как самое близкое здесь. На данный момент я получаю синтаксическую ошибку, рядом с select, но она не показывает ошибку. – BonifatiusK

+0

ah нашел ошибку;) неправильная копия: P – BonifatiusK

-2

Взгляните на то, как http://www.techfounder.net/2009/02/02/selecting-closest-values-in-mysql/

Какой язык вы используете, чтобы эхо из данных?

+0

Почему это получает минус? –

+0

потому что это не ответ. это «пойти сюда, чтобы увидеть ответ». Ответы только на связь - это не ответы. например если эта связь умирает, тогда ваш ответ становится бесполезным. –

+0

И ответы должны быть ответами, а не вопросами. Чтобы запросить разъяснения, используйте комментарий. –

2

Вы можете сделать это с помощью сложной case:

select (case least(abs(d1 - 20), abs(d2 - 20), abs(d3 - 20), abs(d4 - 20)) 
      when abs(d1 - 20) then 'd1' 
      when abs(d2 - 20) then 'd2' 
      when abs(d3 - 20) then 'd3' 
      when abs(d4 - 20) then 'd4' 
     end) 
from mytable; 

Примечание: Это должно иметь более высокую производительность, чем нормализации данных с использованием union all. Однако, как комментарий к структуре данных, вы, вероятно, захотите сохранить значения в отдельных строках, а не в отдельных столбцах. Наличие отдельных столбцов с по существу одинаковыми значениями обычно предполагает необходимость в таблице соединений.

+0

Кажется, SQLlite не знает «наименее» – BonifatiusK

+0

@BonifatiusK. , , Вопрос помечен как «mysql» (также). –

+0

Я знаю, ответ правильный, но не для sqllite. В следующий раз я буду более ясным. Спасибо за вашу помощь! – BonifatiusK