Domanda

Aggiunto: lavorare con SQL Server 2000 e 2005, quindi deve funzionare su entrambi. Inoltre, value_rk non è un numero / numero intero (errore: l'identificatore univoco del tipo di dati Operando non è valido per l'operatore minimo)

Esiste un modo per eseguire una singola colonna "DISTINCT" corrispondenza quando non mi importa delle altre colonne restituite? Esempio:

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

Devo restituire solo una di queste righe in base a ciò che è nel primo (Valore A). Ho ancora bisogno di risultati dalla seconda e terza colonna (la seconda dovrebbe effettivamente corrispondere a tutti i livelli comunque, ma la terza è una chiave unica, di cui ho bisogno almeno di una).

Ecco cosa ho ottenuto finora, anche se ovviamente non funziona:

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

Sto lavorando in ColdFusion, quindi se c'è una semplice soluzione in ciò sono aperto anche a quello. Sto cercando di limitare o " raggruppare per " la prima colonna "valore". value_rk è il mio grosso problema poiché ogni valore è unico ma ne ho solo bisogno.

NOTA: value_rk non è un numero, quindi NON FUNZIONA

AGGIORNAMENTO: ho una versione funzionante, probabilmente è un po 'più lenta di una versione SQL pura, ma onestamente tutto ciò che funziona a questo punto è meglio di niente. Prende i risultati dalla prima query, esegue una seconda query tranne limitandone i risultati a uno e acquisisce un valore_rk corrispondente per il valore corrispondente. In questo modo:

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

Quindi il gioco è fatto, selezionando una singola colonna distintamente in ColdFusion. Qualsiasi suggerimento su SQL Server 2000/2005 è ancora molto gradito :)

È stato utile?

Soluzione

potrebbe funzionare:

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

.. non testato.

Altri suggerimenti

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;

In altre parole, trova la riga a1 per la quale non esiste alcuna riga a2 con lo stesso valore e un value_rk maggiore .

Questo dovrebbe funzionare per PostgreSQL, non so quali dbms usi.

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

PostgreSQL Docs

È questo quello che stai cercando?

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 è unico, dovrebbe funzionare.

Ok, ecco i miei presupposti:

SQL Server standard

value_rk non è un valore numerico, ma value e attributo_definizione_id sono numerici.

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 uno di questi campi non è numerico, richiederà più riflessione. Fatecelo sapere.

Se sei aperto all'utilizzo delle variabili di tabella, puoi tenerlo tutto all'interno di una singola chiamata al database in questo modo:

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

Essenzialmente stai creando un recordset limitato con la tabella riempita con valori univoci di 'valore' e lasciando che SQL Server riempia gli spazi usando solo una delle corrispondenze dalla tabella principale.

Modificato per aggiungere: questa sintassi funziona perfettamente con 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

NON TESTATO!

Non sono sicuro di comprendere appieno il tuo set-up, ma farei qualcosa del genere:

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

Ancora una volta, non sono sicuro di quale colonna stai cercando di limitare o di come vuoi limitarla.

Meno elegante di quanto vorrei ---- è essenzialmente quello che stai facendo, solo in puro SQL --- ma funziona e può essere fatto tutto in 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

Puoi aggiungere un depVal2 e altri usando questo metodo.

penso

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

lavorato

Come notato da John Fiala, la risposta canonica in SQL Server è quella di utilizzare una clausola group by quando si desidera eseguire un "distinto" operazione su un sottoinsieme di colonne. Perché questa è la risposta canonica corretta? Bene, vuoi inserire colonne che non fanno parte del tuo "distinto" gruppo. Esattamente quali righe vuoi inserire per queste colonne sussidiarie? L'uso di una clausola group by e la definizione di funzioni aggregate per queste colonne sussidiarie rende la tua query ben educata, nel senso che ora sai come si ottengono queste colonne sussidiarie. Questo articolo fornisce maggiori dettagli:

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

Inoltre, vale la pena notare che MIN e MAX funzionano sul testo e su molti altri tipi di dati che non sono valori numerici.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top