Question

Ajouté: Travailler avec SQL Server 2000 et 2005, doit donc fonctionner sur les deux. De plus, valeur_rk n'est pas un nombre / entier (Erreur: le type de données opérande, identificateur unique, n'est pas valide pour l'opérateur min)

Existe-t-il un moyen de créer une seule colonne "DISTINCT"? correspondre quand je me fiche des autres colonnes retournées? Exemple:

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

Je dois renvoyer une seule de ces lignes en fonction de ce qui se trouve dans la première (valeur A). J'ai encore besoin des résultats des deuxième et troisième colonnes (la deuxième doit en fait correspondre de toute façon, mais la troisième est une clé unique dont j'ai besoin d'au moins un).

Voici ce que j'ai jusqu'à présent, bien que cela ne fonctionne évidemment pas:

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

Je travaille dans ColdFusion, donc s’il existe une solution de contournement simple, je suis également ouvert à cela. J'essaie de limiter ou de "grouper par". la première colonne "valeur". value_rk est mon gros problème car chaque valeur est unique mais je n’en ai besoin que d’une seule.

REMARQUE: valeur_rk n'est pas un nombre, donc cela ne fonctionne pas

UPDATE: J'ai une version qui fonctionne, elle est probablement un peu plus lente qu'une version purement SQL, mais honnêtement, tout ce qui fonctionne à ce stade vaut mieux que rien. Il prend les résultats de la première requête, effectue une seconde requête, à l'exception de la limiter à une, et récupère un value_rk correspondant pour la valeur correspondante. Comme si:

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

Vous y êtes donc, en sélectionnant une seule colonne distinctement dans ColdFusion. Toutes les suggestions concernant SQL Server 2000/2005 sont toujours les bienvenues:)

Était-ce utile?

La solution

cela pourrait fonctionner:

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

Autres conseils

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;

En d’autres termes, recherchez la ligne a1 pour laquelle aucune ligne a2 n’existe avec le même valeur et un plus grand value_rk .

Cela devrait fonctionner pour PostgreSQL, je ne sais pas quel dbms vous utilisez.

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

Documents PostgreSQL

Est-ce ce que vous cherchez?

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

Si valeur_rk est unique, cela devrait fonctionner.

D'accord, voici mes hypothèses:

Serveur SQL standard

valeur_rk n'est pas une valeur numérique, mais valeur et attribut_définition_attribut sont numériques.

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)

Si l'un de ces champs n'est pas numérique, vous devrez alors y réfléchir plus longuement. Merci de nous le faire savoir.

Si vous êtes ouvert à l'utilisation de variables de table, vous pouvez tout conserver dans un seul appel de base de données, comme suit:

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

Vous créez essentiellement un jeu d'enregistrements limité avec la table remplie de valeurs uniques de 'valeur' ??et laissez SQL Server combler les lacunes en n'utilisant qu'une des correspondances de la table principale.

Modifié pour ajouter: cette syntaxe fonctionne parfaitement dans 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 TESTÉ!

Je ne sais pas si je comprends tout à fait votre configuration, mais j'aimerais quelque chose comme ceci:

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

Encore une fois, je ne suis pas vraiment sûr de la colonne que vous essayez de limiter ou de la façon dont vous voulez la limiter.

Moins élégant que je ne le voudrais ---- c'est essentiellement ce que vous faites, juste en SQL pur --- mais cela fonctionne et peut être fait en 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

Vous pouvez ajouter un depVal2 et d’autres en utilisant cette méthode.

je pense

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

travaillé

Comme l’a noté John Fiala, la réponse canonique dans SQL Server consiste à utiliser une clause group by lorsque vous souhaitez effectuer une opération "distinct". opération sur un sous-ensemble de colonnes. Pourquoi est-ce la bonne réponse canonique? Eh bien, vous souhaitez insérer des colonnes qui ne font pas partie de votre " distinct " groupe. Quelles lignes voulez-vous extraire exactement pour ces colonnes secondaires? L'utilisation d'une clause group by et la définition de fonctions d'agrégation pour ces colonnes auxiliaires rendent votre requête bien gérée en ce sens que vous savez maintenant comment ces colonnes auxiliaires sont obtenues. Cet article donne plus de détails:

http: // blogs. 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

De plus, il convient de noter que MIN et MAX fonctionnent avec du texte et plusieurs autres types de données qui ne sont pas des valeurs numériques.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top