2010-05-31 2 views
1

У меня есть таблица x, что это как один ниже:как выбрать отдельные строки для столбца

id | name | observed_value | 
1 | a | 100   | 
2 | b | 200   | 
3 | b | 300   | 
4 | a | 150   | 
5 | c | 300   | 

Я хочу, чтобы сделать запрос, чтобы в наборе результатов у меня есть ровно одна запись для одного имени:

(1, a, 100) 
    (2, b, 200) 
    (5, c, 300) 

Если в таблице выше указано несколько записей, соответствующих названию, скажите «a», я просто возьму один из них.

В моей текущей реализации я сделать запрос, как это:

select x.* from x , 
(select distinct name, min(observed_value) as minimum_val 
from x group by name) x1 
where x.name = x1.name and x.observed_value = x1.observed_value; 

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

EDIT

Я использую MySQL и моя таблица содержит более трех столбцов, показанных здесь, так что мне кажется, что внутренний запрос не может выполнить мое требование.

+0

Я уверен, что это было задано раньше, но я не могу найти его :( –

+0

Какой механизм базы данных вы используете (например, MySQL, MS-SQL)? – Senseful

+0

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

ответ

3
SELECT t.* 
FROM (
     SELECT DISTINCT name 
     FROM mytable 
     ) q 
JOIN mytable t 
ON  t.id = 
     (
     SELECT id 
     FROM mytable ti 
     WHERE ti.name = q.name 
     ORDER BY 
       ti.name, ti.observed_value, ti.id 
     LIMIT 1 
     ) 

Создать индекс на (name, observed_value, id) для этого запроса, чтобы быть эффективным.

+0

Спасибо за ответ. Но когда я запускаю это, он медленнее моего текущего запроса, который находится в моем вопросе descritpion. – satoru

+0

@Satoru: Вы создали индекс, который я предложил? – Quassnoi

+0

Пока нет.Но я думаю, что мое решение также ускорится, если я создам эти индексы, или я что-то упустил? – satoru

1

Используйте только группу по

select id, name, min(observed_value) as minimum_val from x group by name; 
+1

Этот запрос приведет к ошибке: идентификатор столбца не является частью предложения group by, и для него не задана агрегированная функция. – Tommi

+0

@Tommi Unless OP использует MySQL –

+2

@Martin: в 'MySQL', этот запрос не будет терпеть неудачу, однако' MIN (observ_value) 'и' id' не гарантированно возникнет из одной записи (и, скорее всего, не будет) – Quassnoi

0

Вашего запроса выглядит слишком сложными для ваших целей ... просто группа запроса по имени столбца и использовать агрегатную функцию для остальных столбцов. Например

SELECT name, min(id), min(observed_value) FROM x GROUP BY name 

(Очевидно, что выбрать агрегатную функцию, кроме min если вы хотите получить другие значения для каждого имени.)

1

Поскольку вы не указать, какую СУБД вы используете, я обеспечу несколько решений:

Если вы используете СУБД, которая имеет агрегатную функцию FIRST(), вы можете использовать:

SELECT 
    FIRST(id) as id, 
    name, 
    FIRST(observed_value) as observed_value 
FROM x 
GROUP BY name; 

I Если вы используете MySQL, вы можете использовать ORDER BY в сочетании с LIMIT, чтобы получить что-то похожее на функцию агрегации FIRST().

SELECT 
    (SELECT x2.id 
    FROM x as x2 
    WHERE x2.name = x.name 
    ORDER BY observed_value ASC 
    LIMIT 1 
) AS id, 
    name, 
    MIN(observed_value) as observed_value 
FROM x 
GROUP BY name 
Смежные вопросы