2009-12-17 5 views
0

J'ai une table où dans une table appelée test qui ont 4 champ fields.one nommé comme une liste, j'ai 1,2,3,4,5,6 valeurs multiples séparées par une virgule, je dois vérifier si dans cette table et dans ce domaine particulier, un ID dit 4 est là ou pas .. par une requête sql.SQL complexe de requête

+3

Quelle est la saveur de SQL? –

+0

Django a un type de champ appelé CommaSeparatedIntegerField qui, selon moi, est stocké dans la base de données sous forme de texte. J'ai du mal à trouver comment fonctionne l'interaction avec la base de données pour ce genre de choses. –

Répondre

-3

Que pensez-vous de cela?

Select * From Foo Where Col like '%4%' 
+0

ou avez-vous besoin de voir s'il y avait 4 ', – aaron

+3

qui ne fonctionnera pas s'il a des nombres plus grands que 10 – Drevak

-1

Si vous devez trouver 4 et seulement 4 (et non 14 ou 24 ou 40, etc.), vous devez utiliser

SELECT * FROM foo WHERE col LIKE '%, 4,%' 

ou

SELECT * FROM foo WHERE col LIKE '%,4,%' 

s'il n'y a pas d'espace entre les virgules et les nombres

+0

qui ne fonctionnera pas pour "4,5,6" ou juste "4" – Thilo

+1

c'est vrai, mais personnellement dans cette situation, j'écrirais le code qui envoie la chaîne à la base de données pour inclure une virgule au début et à la fin - ou un espace au début et une virgule à la fin et supprimer la première virgule de la requête - pour que la requête fonctionne toujours. – AndrewDFrazier

4

Votre conception de base de données est incorrecte, c'est pourquoi vous avez des problèmes d'interrogation des données. Vous devriez avoir les valeurs dans un tableau séparé, de sorte que la valeur d'apprentissage est dans son propre domaine. Ensuite, il serait facile de trouver les dossiers:

select t.testId 
from test t 
inner join listing l on l.testId = t.testId 
where l.id = 4 

Maintenant, vous devez utiliser une comparaison de chaînes laides pour trouver les enregistrements:

select testId 
from test 
where ','+listing+',' like '%,4,%' 
4

Vous pouvez

SELECT * 
FROM YourTable 
WHERE REPLACE(Col, ' ', '') LIKE '4,%' --Starts with 
OR REPLACE(Col, ' ', '') LIKE '%,4' --Ends with 
OR REPLACE(Col, ' ', '') LIKE '%,4,%' --Contains 
OR REPLACE(Col, ' ', '') = '4' --Equals 

Tout comme une question d'intérêt, un coup d'oeil à ce

DECLARE @delimiter NVARCHAR(5), 
     @Val INT 

SELECT @Val = 40 

SELECT @delimiter = ',' 

DECLARE @YourTable TABLE(
     ID INT, 
     Vals VARCHAR(50) 
) 

INSERT INTO @YourTable (ID,Vals) SELECT 1, '1,2,3,4,5,6,7,8' 

DECLARE @TempTable TABLE(
     ID INT, 
     Vals XML 
) 

INSERT INTO @TempTable 
SELECT ID, 
     CAST('<d>' + REPLACE(Vals, @delimiter, '</d><d>') + '</d>' AS XML) 
FROM @YourTable 

SELECT * 
FROM @TempTable tt 
WHERE EXISTS(
      SELECT T.split.value('.', 'nvarchar(max)') AS data 
      FROM tt.Vals.nodes('/d') T(split) 
      WHERE T.split.value('.', 'nvarchar(max)') = @Val 
) 
+0

et ensuite vous devez tenir compte des espaces entre les virgules, .... +1 cependant. –

+0

Vous n'avez pas à tenir compte des espaces entre les virgules, en supposant que le format exact est corrigé. – Thilo

+0

@Thilo: vous êtes sur la bonne voie mais je ne compterais pas dessus. –

0

Vous pouvez utiliser une fonction instring dans la clause where et dans la clause select :

Oracle:

select substr(column, instr(column, '1', 1), 1) 
where instr(column, '1', 1) > 0 

fonctionne que si vous voulez une valeur unique. Vous pouvez également utiliser une combinaison de déclarations de cas ou de décodage pour créer une seule colonne pour chaque valeur possible:

select 
decode(instr(column, '1', 1), 0, substr(column, instr(column, '1', 1), 1), null) c1, 
decode(instr(column, '2', 1), 0, substr(column, instr(column, '2', 1), 1), null) c2, 
decode(instr(column, '3', 1), 0, substr(column, instr(column, '3', 1), 1), null) c3 

La beauté de cette approche pour un tel ensemble mal normalisé de données est que vous pouvez enregistrer comme vue et puis exécutez SQL sur cela, donc si vous enregistrez ce qui précède, vous pouvez utiliser:

select c1, c2 from view where c1 is not null or c2 is not null 

NB. Dans d'autres dbms, vous devrez peut-être utiliser une syntaxe différente, éventuellement le cas plutôt que l'instruction de décodage