Вопрос

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

Есть ли способ сделать "ОТЛИЧНОЕ" совпадение для одного столбца, когда меня не волнуют другие возвращаемые столбцы?Пример:

**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, но, честно говоря, все, что работает на данный момент, лучше, чем ничего.Он принимает результаты из первого запроса, выполняет второй запрос, за исключением ограничения его результатов одним, и получает соответствующее значение_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 по-прежнему приветствуются :)

Это было полезно?

Решение

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

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

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

Другие советы

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_rk .

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

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

Документы PostgreSQL

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

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 уникально, это должно работать.

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

Стандартный 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)

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

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

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 очень хорошо.

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

НЕ ИСПЫТАНО!

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

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

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

Менее элегантно, чем хотелось бы - это, по сути, то, что вы делаете, просто на чистом 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 VALUE=@keyVal 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 и другие, используя этот метод.

я думаю , что

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

сработало

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top