Выберите один столбец DISTINCT SQL

Добавлено: Работа с SQL Server 2000 и 2005, так что нужно работать на обоих. Кроме того, value_rk не является числом/целым числом (ошибка: уникальный идентификатор типа данных операнда недействителен для оператора min)

Есть ли способ сделать один столбец "DISTINCT", когда мне не нужны остальные столбцы? Пример:

**Table**
Value A, Value L, Value P
Value A, Value Q, Value Z

Мне нужно вернуть только одну из этих строк на основе того, что находится в первом (значение A). Мне все еще нужны результаты из второго и третьего столбцов (второй должен фактически совпадать по всем направлениям, но третий - это уникальный ключ, для которого мне нужен хотя бы один из них).

Вот что я получил до сих пор, хотя это не работает явно:

SELECT value, attribute_definition_id, value_rk
FROM attribute_values
WHERE value IN (
    SELECT value, max(value_rk)
    FROM attribute_values
)
ORDER BY attribute_definition_id

Я работаю в ColdFusion, поэтому, если есть простой обходной путь, я также открыт для этого. Я пытаюсь ограничить или "группировать по" значение первого столбца. value_rk - моя большая проблема, так как каждое значение уникально, но мне нужно только одно.

ПРИМЕЧАНИЕ: значение_rk не является числом, поэтому это НЕ РАБОТАЕТ

UPDATE: У меня рабочая версия, она, вероятно, довольно медленная, чем чистая SQL-версия, но, честно говоря, все, что работает на этом этапе, лучше, чем ничего. Он принимает результаты первого запроса, выполняет второй запрос, за исключением того, что он приводит к одному, и захватывает соответствующее значение_rk для значения, которое соответствует. Например:

<cfquery name="queryBaseValues" datasource="XXX" timeout="999">
    SELECT DISTINCT value, attribute_definition_id
    FROM attribute_values
    ORDER BY attribute_definition_id
</cfquery>

<cfoutput query="queryBaseValues">
    <cfquery name="queryRKValue" datasource="XXX">
        SELECT TOP 1 value_rk
        FROM attribute_values
        WHERE value = '#queryBaseValues.value#'
    </cfquery>
    <cfset resourceKey = queryRKValue.value_rk>
    ...

Итак, у вас это есть, выбирая один столбец в ColdFusion. Любые чистые предложения SQL Server 2000/2005 по-прежнему очень приветствуются:)

Ответы

Ответ 1

это может сработать:

SELECT DISTINCT a.value, a.attribute_definition_id, 
  (SELECT TOP 1 value_rk FROM attribute_values WHERE value = a.value) as value_rk
FROM attribute_values as a
ORDER BY attribute_definition_id

.. не проверен.

Ответ 2

SELECT a1.value, a1.attribute_definition_id, a1.value_rk
FROM attribute_values AS a1
  LEFT OUTER JOIN attribute_values AS a2
    ON (a1.value = a2.value AND a1.value_rk < a2.value_rk)
WHERE a2.value IS NULL
ORDER BY a1.attribute_definition_id;

Другими словами, найдите строку a1, для которой не существует строки a2 с тем же value и большим value_rk.

Ответ 3

Это должно работать для PostgreSQL, я не знаю, какие dbms вы используете.

SELECT DISTINCT ON (value)
  value, 
  attribute_definition_id, 
  value_rk
FROM 
  attribute_values
ORDER BY
  value, 
  attribute_definition_id

Документы PostgreSQL

Ответ 4

Это то, что вы ищете?

SELECT value, attribute_definition_id, value_rk
FROM attribute_values av1
WHERE value_rk IN (
        SELECT max(value_rk)
        FROM attribute_values av2
        WHERE av2.value = av1.value
)
ORDER BY attribute_definition_id

Если значение_rk уникально, это должно работать.

Ответ 5

Хорошо, здесь мои предположения:

Стандартный SQL Server

Значение_rk не является числовым значением, но value и attribute_definition_id являются числовыми.

SELECT value_rk, MIN(value) as value, MIN(attribute_definition_id) as attribute_definition_id
FROM attribute_values
GROUP BY value_rk
ORDER BY MIN(attribute_definition_id)

Если одно из этих полей не является числовым, тогда потребуется больше размышлений - сообщите нам.

Ответ 6

Если вы открыты для использования переменных таблицы, вы можете сохранить все это в одном вызове базы данных следующим образом:

DECLARE @attribute_values TABLE (value int, attribute_definition_id int, value_rk uniqueidentifier)

INSERT INTO @attribute_values (value)
SELECT DISTINCT value FROM attribute_values

UPDATE @attribute_values
SET attribute_definition_id = av2.attribute_definition_id,
    value_rk = av2.value_rk
FROM @attribute_values av1
INNER JOIN attribute_values av2 ON av1.value = av2.value

SELECT value, attribute_definition_id, value_rk FROM @attribute_values

По существу вы создаете ограниченный набор записей с таблицей, заполненной уникальными значениями "значение", и позволяя SQL Server заполнить пробелы, используя только одно из совпадений из основной таблицы.

Отредактировано для добавления: этот синтаксис работает в пределах cfquery просто отлично.

Ответ 7

SELECT value, attribute_definition_id, value_rk
FROM attribute_values
WHERE value, value_rk IN (
        SELECT value, max(value_rk)
        FROM attribute_values
        GROUP BY value
)
ORDER BY attribute_definition_id

НЕ ИСПЫТЫВАЕТСЯ!

Ответ 8

Я не уверен, что полностью понимаю вашу настройку, но будет что-то вроде этой работы:

SELECT value, attribute_definition_id, value_rk
FROM attribute_values
GROUP BY value
ORDER BY attribute_definition_id;

Опять же, я не уверен, какой столбец вы пытаетесь ограничить, или как вы хотите его ограничить.

Ответ 9

Менее изящный, чем мне хотелось бы ---- это, по сути, то, что вы делаете, только в чистом SQL --- но оно работает и может быть выполнено в SQL.

DECLARE @mytable TABLE(mykey NVARCHAR(512), myVal NVARCHAR(512))

DECLARE @keyVal NVARCHAR(512)
DECLARE @depVal NVARCHAR(512)
DECLARE myCursor CURSOR for
   SELECT DISTINCT(value) FROM attribute_values
OPEN myCursor
FETCH NEXT FROM myCursor INTO @keyVal
WHILE @@FETCH_STATUS=0
  BEGIN
     SET @depVal = (SELECT TOP 1 attribute_definition_id FROM attribute_values WHERE [email protected] ORDER BY attribute_definition_id)
     INSERT INTO @mytable (mykey, myVal) VALUES (@keyVal, @depVal)
     FETCH NEXT FROM myCursor INTO @keyVal
  END
DEALLOCATE myCursor

SELECT * FROM @mytable

Вы можете добавить depVal2 и другие, используя этот метод.

Ответ 10

Я думаю,

SELECT DISTINCT a.value, a.attribute_definition_id, 
(SELECT TOP 1 value_rk FROM attribute_values WHERE value = a.value) as value_rk
FROM attribute_values as a
ORDER BY attribute_definition_id

работал

Ответ 11

Как отметил Джон Фиала, канонический ответ на SQL-сервере заключается в использовании предложения group by, когда вы хотите выполнить "отличную" операцию над подмножеством столбцов. Почему это правильный канонический ответ? Ну, вы хотите вытащить столбцы, которые не являются частью вашей "отличной" группы. Точно, какие строки вы хотите использовать для этих вспомогательных столбцов? Использование предложения group by и определение агрегатных функций для этих вспомогательных столбцов делает ваш запрос корректным в том смысле, что теперь вы знаете, как получить эти вспомогательные столбцы. В этой статье приводится более подробная информация:

http://weblogs.sqlteam.com/jeffs/archive/2007/10/12/sql-distinct-group-by.aspx

SELECT value_rk, MIN(value) as value, 
MIN(attribute_definition_id) as attribute_definition_id
FROM attribute_values
GROUP BY value_rk

Кроме того, стоит отметить, что MIN и MAX работают над текстом и несколькими другими типами данных, которые не являются числовыми значениями.