2009-08-12 14 views
6

J'ai une liste de codes de pays ISO2 que je veux utiliser dans une requête.
Quelque chose comme ceci:Utiliser la liste des valeurs codées en dur dans la requête

select cou, 128,13, 1 
from ('AD', 'AE', 'AF', 'AG', 'AI', 'AL', 'AM', [snip]) as cou 

Mais .. travailler. Je me souviens avoir fait une telle chose par le passé, mais je ne trouve plus de document à ce sujet. C'est une requête en un coup, donc cela ne me dérange pas la performance, la pratique de codage ou la maintenabilité.

Des idées?

MISE À JOUR
Comme Pax a noté, il est en effet plus pratique d'avoir ces données dans ma base de données pour toutes les bonnes raisons. Je comprends son opinion parce que je répondrais pareil. Toutefois, ces données sont déjà dans une autre table, dans une autre base de données, sur un autre serveur, sur un autre réseau.

Pour tester mes requêtes, j'ai besoin de valeurs de prise de vue rapides dans un tableau de cette nouvelle base de données. Je ne veux pas configurer les réseaux, les requêtes inter-serveurs, etc. juste pour tester mes requêtes sur certaines données réelles. J'espère que cela explique pourquoi je vais à contre-courant pour ce one shot.

+2

J'aime comment, malgré mon avertissement, les gens suggèrent toujours que je devrais le mettre dans une table. Ne vous méprenez pas. Je ferais la même chose :) –

Répondre

2

façon en utilisant d'abord l'union:

select 'AD' union all select 'AE' .... 

La seconde - pas évident, mais élégante - en utilisant des requêtes récursives;

declare @x as varchar(200) 
set @x = 'ADAEAFAGAIALAM' 
;with FakeTbl AS (
    SELECT substring(@x, 1, 2) sval, 0 as ROWN 
     WHERE LEN(@x) > 0 
    UNION ALL 
    SELECT substring(@x, (it.ROWN+1)*2+1, 2) sval, it.ROWN+1 as ROWN 
     FROM FakeTbl it 
     WHERE LEN(@x) > (it.ROWN+1)*2 
) 
select sval, ROWN from FakeTbl 

endroits que vous chaîne @x, en supposant que le code a len 2. restriction faible de cette méthode est de niveau récursif (pour 2005, il est 100)

+0

Vous pouvez supprimer la limite de récursivité par défaut en ajoutant OPTION (MAXRECURSION 0) à la fin de votre requête –

+4

Nous semblons avoir des définitions différentes du mot "élégant" :-) – paxdiablo

+0

@Pax - cet exemple est tiré du code réel. Nous venons de créer une fonction table-valeur qui accepte la chaîne varchar (donc au lieu de @x argument d'entrée utilisé). Et cela fonctionne dans plusieurs cas d'utilisation. – Dewfy

4

La meilleure façon de le faire (malgré votre désir de les avoir codées en dur) est de créer une table des codes de pays:

create table iso2_codes (
    code char(2) primary key 
) 
insert into iso2_codes (code) vales ('AD'); 
insert into iso2_codes (code) vales ('AE'); 
: : : 
insert into iso2_codes (code) vales ('AM'); 

Ensuite il suffit d'utiliser

select code, 128, 13, 1 from iso2_codes; 

I Je suis convaincu que les données doivent être stockées dans des tables où elles peuvent être facilement modifiées, et non intégrées au code source ou aux scripts, où c'est un cauchemar à traquer et à modifier.

C'est mon opinion, d'autres peuvent être en désaccord.

+0

+1. Même si les autres réponses vous donnent une solution à ce que vous demandez, vous devriez vous arrêter et réfléchir à ce qu'il vous en coûtera pour le maintenir. –

+0

Le problème est que les données sont dans une autre base de données et doit être mis dans cette table sur un autre serveur. Il faudrait plus de travail à MUCh pour configurer le réseau, les connexions, les droits et les requêtes inter-serveurs, puis sélectionnez-les et insérez-les dans cette liste. –

+0

J'ai ajouté quelques informations dans l'OP à cet égard –

3

réponse de Pax est l'approche correcte. Mais si vous insistez pour le faire en ligne:

select cou, 128,13, 1 
from (select 'AD' as cou 
     union all select 'AE' 
     union all select 'AF' 
     union all select 'AG' 
     union all select 'AI' 
     union all select 'AL' 
     union all select 'AM') as X 
12

Valeurs mot-clé peut être utilisé pour y parvenir.

select col1, 128 col2, 13 col3, 1 col4 
from (values ('AD'), ('AE'), ('AF'), ('AG'), ('AI'), ('AL'), ('AM')) as x (col1) 
+0

Cela devrait être marqué comme la bonne réponse, quelle que soit votre compréhension de l'élégance. Pour rejoindre, 'SELECT * FROM RealTable INNER JOIN (VALEURS ('une valeur'), ​​('une autre valeur')) AS x (col) ON RealCol = col'. Pour joindre une création cartésienne, 'SELECT * FROM RealTable INNER JOIN (VALEURS ('une valeur'), ​​('une autre valeur')) AS x (col) ON 1 = 1' – Chris

Questions connexes