2009-10-14 11 views
115

J'ai un problème très simple que je ne peux pas résoudre. Je dois faire quelque chose comme ceci:Comment puis-je sélectionner à partir de la liste des valeurs dans SQL Server

select distinct * from (1, 1, 1, 2, 5, 1, 6). 

Quelqu'un peut-il aider?

Modifier

Les données se présente comme un fichier texte d'un de nos clients. Il est totalement non formaté (c'est une très longue ligne de texte), mais il est possible de le faire dans Excel. Mais ce n'est pas pratique pour moi, car je devrai utiliser ces valeurs dans ma requête sql. Ce n'est pas pratique de le faire chaque fois que j'ai besoin d'exécuter une requête.

+0

Voulez-vous sélectionner parmi plusieurs tables ou sélectionner dans une seule table mais avoir des valeurs spécifiques à sélectionner? quelque chose comme identifiant spécifique –

+0

Pas ce que vous demandez, mais vous pouvez le faire dans une autre langue.Par exemple dans PowerShell, vous pouvez faire '$ d = (1, 1, 1, 2, 5, 1, 6) | sort -Unique' pour obtenir les valeurs distinctes dans un tableau '$ d'. Facile à étendre à un outil de fichier à fichier. –

Répondre

59

La manière la plus simple d'obtenir les valeurs distinctes d'une longue liste de texte délimité par des virgules serait d'utiliser un trouver un remplacer par UNION pour obtenir les valeurs distinctes.

SELECT 1 
UNION SELECT 1 
UNION SELECT 1 
UNION SELECT 2 
UNION SELECT 5 
UNION SELECT 1 
UNION SELECT 6 

appliquée à votre longue ligne de texte délimité par des virgules

  • Rechercher et remplacer chaque virgule avec UNION SELECT
  • Ajouter un SELECT devant la déclaration

Vous devriez maintenant avoir une requête de travail

+2

non, non, j'ai une liste de plusieurs centaines de valeurs, manuellement ce serait la torture – Eedoh

+0

d'où vient cette liste? Il pourrait être beaucoup plus facile de simplement copier/coller cette liste dans Excel et extraire les valeurs distinctes à l'aide d'un simple tableau croisé. –

+0

btw, trouver et remplacer pourrait aussi vous prendre un long chemin. Remplacez chaque virgule par * union select *, ajoutez un select à l'avant et vous devriez avoir une requête de travail cfr l'union que j'ai montrée. –

16

Si vous voulez pour ne sélectionner que certaines valeurs à partir d'une seule table, vous pouvez essayer cette

select distinct(*) from table_name where table_field in (1,1,2,3,4,5) 

par exemple:

select first_name,phone_number from telephone_list where district id in (1,2,5,7,8,9) 

si vous voulez sélectionner plusieurs tables alors vous devez aller pour UNION.

Si vous voulez juste sélectionner les valeurs 1, 1, 1, 2, 5, 1, 6 alors vous devez le faire

select 1 
union select 1 
union select 1 
union select 2 
union select 5 
union select 1 
union select 6 
+0

Je n'ai pas besoin de sélectionner à partir d'une table, mais de cette liste de valeurs (entre parenthèses). C'est le problème principal (sélection d'un tableau de valeurs séparées par des virgules, pas d'une table) – Eedoh

+0

dans ce cas, comme nous avons la table DUAL dans Oracle, vous pouvez utiliser le même. Mais puisqu'il n'y a pas de DUAL, alors vous devrez suivre la voie de l'union. Vous pouvez essayer une autre méthode, comme vous l'avez mentionné, vous avez un tableau de valeurs séparées par des virgules, pourquoi ne pas les insérer dans une table et ensuite utiliser une requête select select, au lieu d'utiliser autant de syndicats sql. –

9

Cela fonctionne sur SQL Server 2005 et s'il y a nombre maximal:

SELECT * 
FROM 
    (SELECT ROW_NUMBER() OVER(ORDER BY a.id) NUMBER 
    FROM syscomments a 
    CROSS JOIN syscomments b) c 
WHERE c.NUMBER IN (1,4,6,7,9) 
+1

+1 propre mais il est limité à la quantité de lignes de syscomments croisées jointes à lui-même. Dans mon cas à 294849. (et vous avez oublié distinct.) –

+0

Vous pouvez croiser rejoindre une fois de plus, mais le remplacement des virgules est une solution beaucoup plus rapide. – LukLed

+0

Oui, c'est bien aussi, mais je préfère la solution de Lieven, à cause de la simplicité. – Eedoh

248

Disponible uniquement sur SQL Server 2008 et plus est rangée constructeur sous cette forme:
Vous pouvez utiliser

SELECT DISTINCT * FROM (VALUES (1), (1), (1), (2), (5), (1), (6)) AS X(a) 

Beaucoup ont écrit au sujet, parmi eux:

+28

Note de côté: 'X' est un alias pour le nom de la table et' a' est un alias pour le nom de la colonne;). –

+4

Ceci est la réponse la plus correcte par rapport à celle actuellement sélectionnée –

+0

C'est la manière la plus générique, j'ai été gâté par unnest (ARRAY []) dans 'pgsql' et maintenant frapper la tête pour faire accepter des valeurs mineures comme des enregistrements de ligne dans' sqlserver', et c'est ici. Heureux de savoir. – Ben

9

PostgreSQL vous donne 2 façons de le faire:

SELECT DISTINCT * FROM (VALUES('a'),('b'),('a'),('v')) AS tbl(col1) 

ou

SELECT DISTINCT * FROM (select unnest(array['a','b', 'a','v'])) AS tbl(col1) 

approche de tableau à l'aide, vous pouvez aussi faire quelque chose comme ceci:

SELECT DISTINCT * FROM (select unnest(string_to_array('a;b;c;d;e;f;a;b;d', ';'))) AS tbl(col1) 
+8

Bien que la question spécifie MSSQL ... ':)' – halfer

-1

Une technique qui a fonctionné pour moi est d'interroger une table que vous connaissez a une grande quantité d'enregistrements, y compris tout le champ ROW_NUMBER dans votre résultat

Select Top 10000 Row_Number() OVER (Order by fieldintable) As 'recnum' From largetable 

renvoie un jeu de résultats de 10000 enregistrements de 1 à 10000, utiliser dans une autre requête pour vous donner les résultats souhaités

-1

utilisez le plaisir SQL In ction

Quelque chose comme ceci:

SELECT * FROM mytable WHERE: 
"VALUE" In (1,2,3,7,90,500) 

Works un traitement dans ArcGIS

+0

Ce SELECT génère une erreur de syntaxe avec SQL Server. – JohnH

32

Avez-vous essayé d'utiliser la syntaxe suivante?

select * from (values (1), (2), (3), (4), (5)) numbers(number) 
+4

un utilisateur anonyme a suggéré de modifier le code pour: 'SELECT DISTINCT nom_table.nom_colonne FROM (VALUES (1), (2), (3)) AS nom_table (nom_colonne)' – Vogel612

0

Une autre façon que vous pouvez utiliser est une requête comme ceci:

SELECT DISTINCT 
    LTRIM(m.n.value('.[1]','varchar(8000)')) as columnName 
FROM 
    (SELECT CAST('<XMLRoot><RowData>' + REPLACE(t.val,',','</RowData><RowData>') + '</RowData></XMLRoot>' AS XML) AS x 
    FROM (SELECT '1, 1, 1, 2, 5, 1, 6') AS t(val) 
    ) dt 
    CROSS APPLY 
    x.nodes('/XMLRoot/RowData') m(n); 
24

En général:

SELECT 
    DISTINCT 
    FieldName1, FieldName2, ..., FieldNameN 
FROM 
    (
    Values 
    (ValueForField1,ValueForField2,...,ValueForFieldN), 
    (ValueForField1,ValueForField2,...,ValueForFieldN), 
    (ValueForField1,ValueForField2,...,ValueForFieldN), 
    (ValueForField1,ValueForField2,...,ValueForFieldN), 
    (ValueForField1,ValueForField2,...,ValueForFieldN) 
)AS TempTableName (FieldName1, FieldName2, ..., FieldNameN) 

Dans votre cas:

Select 
    distinct 
    TempTableName.Field1 
From 
    (
    VALUES 
    (1), 
    (1), 
    (1), 
    (2), 
    (5), 
    (1), 
    (6) 
) AS TempTableName (Field1) 
0

Si vous avez besoin un tableau, séparez les colonnes du tableau par une virgule:

SELECT * FROM (VALUES('WOMENS'),('MENS'),('CHILDRENS')) as X([Attribute]) 
,(VALUES(742),(318)) AS z([StoreID]) 
Questions connexes