Выберите один столбец DISTINCT SQL - PullRequest
14 голосов
/ 30 октября 2008

Добавлено: Работа с 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 - моя большая проблема, поскольку каждое значение уникально, но мне нужно только одно.

ПРИМЕЧАНИЕ: value_rk не является числом, следовательно, это НЕ РАБОТАЕТ

ОБНОВЛЕНИЕ: у меня есть рабочая версия, она, вероятно, немного медленнее, чем чистая версия SQL, но, честно говоря, все, что работает на этом этапе, лучше, чем ничего. Он берет результаты первого запроса, выполняет второй запрос, за исключением ограничения его результатов одним, и получает совпадающее значение value_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 по-прежнему приветствуются:)

Ответы [ 11 ]

11 голосов
/ 31 октября 2008

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

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

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

8 голосов
/ 30 октября 2008

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

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

Документы PostgreSQL

8 голосов
/ 30 октября 2008
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.

2 голосов
/ 06 ноября 2008

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

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

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

Отредактировано, чтобы добавить: Этот синтаксис прекрасно работает в cfquery.

2 голосов
/ 30 октября 2008

Хорошо, вот мои предположения:

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

value_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)

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

2 голосов
/ 30 октября 2008

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

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

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

1 голос
/ 30 октября 2008

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

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

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

1 голос
/ 30 октября 2008
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

НЕ ИСПЫТАНО!

0 голосов
/ 31 августа 2012

Как отметил Джон Фиала, каноническим ответом на 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 работают с текстом и некоторыми другими типами данных, которые не являются числовыми значениями.

0 голосов
/ 06 января 2012

я думаю

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

работал

...