Selecione uma SQL DISTINCT coluna
-
05-07-2019 - |
Pergunta
Adicionado: Trabalho com o SQL Server 2000 e 2005, por isso tem que trabalhar em ambos. Além disso, value_rk não é um número / inteiro (Erro: tipo de dados Operando uniqueidentifier é inválida para o operador min)
Existe uma maneira de fazer uma única coluna jogo "DISTINCT" quando eu não se preocupam com as outras colunas retornados? Exemplo:
**Table**
Value A, Value L, Value P
Value A, Value Q, Value Z
Eu preciso retornar apenas uma dessas linhas com base no que é no primeiro (Value A). Eu ainda preciso de resultados do segundo e colunas terceiros (o segundo deve realmente corresponder a todos através da placa de qualquer maneira, mas a terceira é uma chave única, que eu preciso de pelo menos um dos).
Aqui está o que eu tenho até agora, embora ele não funciona, obviamente:
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
Eu estou trabalhando em ColdFusion por isso, se há uma solução simples em que estou aberto a isso também. Estou tentando limitar ou "grupo por" "valor" da primeira coluna. value_rk é o meu grande problema uma vez que cada valor é único, mas eu só precisa de um.
NOTA: value_rk não é um número, portanto, isso não funciona
UPDATE: Eu tenho uma versão de trabalho, é provavelmente um pouco mais lento do que uma versão SQL puro, mas honestamente nada a trabalhar neste momento é melhor do que nada. Leva os resultados da primeira consulta, faz uma segunda consulta exceto limitando os seus resultados para um, e pega uma value_rk correspondente para o valor que corresponda. Como assim:
<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>
...
Então, você tem isso, a seleção de uma única coluna distintamente no ColdFusion. Qualquer SQL Server puro 2000/2005 sugestões ainda são muito bem-vindo:)
Solução
este trabalho poder:
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
.. não testado.
Outras dicas
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;
Em outras palavras, encontrar o a1
linha para a qual não existe a2
linha com o mesmo value
e uma maior value_rk
.
Isso deve funcionar para o PostgreSQL, eu não sei qual dbms que você usa.
SELECT DISTINCT ON (value)
value,
attribute_definition_id,
value_rk
FROM
attribute_values
ORDER BY
value,
attribute_definition_id
É isso que você está procurando?
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
Se value_rk é único, isso deve funcionar.
Ok, aqui está minhas suposições:
padrão SQL Server
value_rk não é um valor numérico, mas valor e attribute_definition_id são numérico.
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)
Se um desses campos não é numérico, então ele vai exigir mais pensamento -. Por favor deixe-nos saber
Se você está aberto ao uso de variáveis ??de tabela, você poderia mantê-lo tudo dentro de uma chamada de banco de dados único como este:
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
Essencialmente, você está criando um conjunto de registros limitada com a mesa cheia de valores exclusivos de 'valor', e deixando preenchimento SQL Server as lacunas usando apenas uma das partidas da tabela principal.
Editado para acrescentar:. Esta sintaxe funciona dentro cfquery muito bem
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
NÃO TESTADO!
Eu não tenho certeza se eu inteiramente compreender o seu set-up, mas seria algo como este trabalho:
SELECT value, attribute_definition_id, value_rk
FROM attribute_values
GROUP BY value
ORDER BY attribute_definition_id;
Mais uma vez, eu não sou real certeza de qual coluna é que você está tentando limitar, ou como você está querendo limitá-lo.
Menos elegante do que eu gostaria ---- é essencialmente o que você está fazendo, apenas no SQL puro --- mas funciona e tudo pode ser feito em 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
Você pode adicionar um depVal2 e outros usando este método.
i pensar
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
trabalhou
Como observado por John Fiala, a resposta canônica no servidor SQL é usar uma cláusula GROUP BY quando você quer executar uma operação "distinta" sobre um subconjunto de colunas. Porque esta é a resposta canônica correto? Bem, você quer puxar em colunas que não fazem parte do seu grupo "distinta". Exatamente o que as linhas que você quer puxar para estas colunas subsidiárias? Usando um grupo por cláusula e definição de funções de agregação para essas colunas subsidiárias faz sua consulta bem-comportado no sentido de que você já sabe como essas colunas subsidiárias são obtidos. Este artigo dá mais detalhes:
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
Além disso, é importante notar que MIN e MAX trabalho em texto e vários outros tipos de dados que não são valores numéricos.