3
votes

SELECT FROM Table O le nombre exact non partiel est dans une chaîne SQL

J'ai une table qui contient un tas de nombres séparés par une virgule.

Je voudrais récupérer des lignes de la table où un nombre exact et non un nombre partiel se trouve dans la chaîne.

EXEMPLE :

CREATE TABLE IF NOT EXISTS `teams` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `uids` text NOT NULL,
  `islive` tinyint(1) NOT NULL DEFAULT '1',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;

INSERT INTO `teams` (`id`, `name`, `uids`, `islive`) VALUES
(1, 'Test Team', '1,2,8', 1),
(3, 'Test Team 2', '14,18,19', 1),
(4, 'Another Team', '1,8,20,23', 1);

Je voudrais chercher où 1 est dans la chaîne.

Actuellement, si j'utilise Contains ou LIKE, il ramène toutes les lignes avec 1 , mais 18, 19 etc n'est pas 1 mais en a 1.

J'ai configuré un sqlfiddle ici

Dois-je faire un regex?


3 commentaires

Et c'est pourquoi vous ne stockez pas de données comme ça dans une table SQL.


Est-il trop tard pour prendre cette structure de table derrière la grange et la tirer, parce que c'est ce que vous devez faire ... Recommencez et structurez correctement ces données et cela vous fera gagner beaucoup de temps et de souffrances sur la route.


La meilleure façon de le faire est probablement d'utiliser une fonction de division de chaîne et de comparer avec les résultats


5 Réponses :


2
votes

Vous pourriez probablement tous les attraper avec un OR

SELECT ...

WHERE uids LIKE '1,%'
OR  uids LIKE '%,1'
OR uids LIKE '%, 1'
OR uids LIKE '%,1,%'
OR uids = '1'


1 commentaires

@Hogan Je ne dis jamais vraiment quand il s'agit de personnes stockant des données qui ne sont pas normalisées.



2
votes

Je rechercherais les quatre emplacements possibles de l'ID que vous recherchez:

  • En tant que seul élément de la liste.
  • En tant que premier élément de la liste.
  • En tant que dernier élément de la liste.
  • En tant qu'élément interne de la liste.

La requête ressemblerait à:

select *
from teams
where uids = '1' -- only
   or uids like '1,%' -- first
   or uids like '%,1' -- last
   or uids like '%,1,%' -- inner


3 commentaires

uids = '1' - uniquement


Ça a changé. Même si LIKE fonctionne, = est plus intuitif.


Ouais, il pourrait être légèrement plus rapide s'il n'a pas besoin d'utiliser la correspondance de motifs.



4
votes

Vous n'avez besoin que d'une condition:

select *
from teams
where concat(',', uids, ',') like '%,1,%'


2 commentaires

@TheImpaler - bien sûr, il ajoute des virgules au début et à la fin.


Espérons simplement qu'il n'y ait pas d'espaces entre les virgules.



0
votes

Vous n'avez pas spécifié la version de SQL Server que vous utilisez, mais si vous utilisez 2016+, vous avez accès à STRING_SPLIT que vous pouvez utiliser dans ce cas. Voici un exemple:

CREATE TABLE #T
     (
        id int,
        string varchar(20)
     )

     INSERT INTO #T
     SELECT 1, '1,2,8' UNION
     SELECT 2, '14,18,19' UNION
     SELECT 3, '1,8,20,23' 


     SELECT * FROM #T
     CROSS APPLY string_split(string, ',')
     WHERE value = 1


0 commentaires

0
votes

Vous SQL Fiddle utilisez MySQL et votre syntaxe est cohérente avec MySQL. Il existe une fonction intégrée à utiliser:

select t.*
from teams t
where find_in_set(1, uids) > 0;

Cela dit, RÉPARER VOTRE MODÈLE DE DONNÉES POUR NE PAS STOCKER LES LISTES DANS UNE SEULE COLONNE. Désolé que cela soit sorti si fort, c'est juste un principe important de conception de base de données.

Vous devriez avoir une table appelée teamUsers avec une ligne par équipe et par utilisateur de cette équipe. Il existe de nombreuses raisons pour lesquelles votre méthode de stockage des données est mauvaise:

  • Les nombres doivent être stockés sous forme de nombres et non de chaînes.
  • Les colonnes doivent contenir une seule valeur.
  • Les relations de clé étrangère doivent être correctement déclarées.
  • SQL (en général) a de mauvaises fonctions de gestion des chaînes.
  • Les requêtes résultantes ne peuvent pas être optimisées.
  • Des choses simples comme la liste des uid dans l'ordre ou la suppression des doublons sont inutilement difficiles.


0 commentaires