sql >> Database teknologi >  >> RDS >> Mysql

Vælg alle, hvor feltet indeholder streng adskilt med komma

Med MySQL kan du bruge FIND_IN_SET() :

SELECT * FROM mytable WHERE FIND_IN_SET('ios ', tags) > 0;

http://dev.mysql .com/doc/refman/5.0/en/string-functions.html#function_find-in-set

Bemærk, at FIND_IN_SET forventer, at strenge er komma adskilt, ikke komma og mellemrum adskilt. Så du kan have problemer med det sidste tag. Den virkelig bedste måde ville være at normalisere tabellen; Ellers kan du fjerne mellemrum fra tags kolonne; endelig kan du omgå problemet ved at tilføje et mellemrum til tags kolonne:

SELECT * FROM mytable WHERE FIND_IN_SET('ios ', CONCAT(tags,' ')) > 0;

Hvis antallet af tags er begrænset, kan du overveje at konvertere kolonnen til et SET . Dette vil i høj grad forbedre effektiviteten.

OPDATERING

Bortset fra at jeg tog mellemrummene forkert . De er før strengene og ikke efter.

Så:

SELECT * FROM mytable WHERE FIND_IN_SET(' ios', CONCAT(' ', tags)) > 0;

Men igen, slip med de mellemrum - de er intet andet end problemer :-)

OPDATERING 2

Ovenstående virker, okay. Men det er næsten alt, du kan sige til min fordel. Ikke kun er løsningen ret *in*effektiv, den gør også systemet nærmest uvedligeholdeligt (been there, done that, fik T-shirten og en udtygget røv under samme). Så jeg vil nu harpe lidt til fordel for normalisering, dvs. at have mindst disse to tabeller mere:

CREATE TABLE tags ( id      INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
                    tagName varchar(32) // I'm a bit of a cheapskate
);
CREATE TABLE has_tag ( tableid INTEGER, tagid INTEGER );

Hvor meget er dette bedre? Lad mig tælle måderne.

  • du kan nemt tilføje mere fleksible forespørgsler ("har alle tags i iOS, C++, ..." eller "har mindst tre tags blandt disse:( iOS, Python, SQL, .NET, Haskell )". Ja, du kan gøre dette med FIND_IN_SET , men tro mig, du vil ikke nyde det .
  • du har en styret ordbog af tags, som giver dig mulighed for at kontrollere, om et tag er kendt (samt nemt at generere lister såsom drop-down kombinationsbokse, eller -- var der nogen, der sagde "jQuery Autocomplete"?).
  • gemmer noget diskfast ejendom (tags skrives én gang)
  • søgninger er hurtige . Hvis du allerede kender de tags, du leder efter, og prækompilerer dem til tag-id'er, vil de efterlade SQL-gummi-scorb-mærker på fortovet, når de kører (indekseret søgning efter et heltal værdi!). Og tags, der ikke vil kompilere, vil ikke være der , og du vil vide dette, allerede inden søgningen starter.
  • gør det meget nemmere at omdøbe tags
  • kan indeholde et hvilket som helst nummer af tags (du risikerer at få nogle tag afkortet til 'iOS Developm' før eller siden...)

Jeg tror, ​​at "CSV-feltet" er cens(eller) blandt SQL-antimønstrene ( http://pragprog.com/book/bksqla/sql-antipatterns ), og med god grund.



  1. Hvordan kan jeg indsætte data i SQL Server ved hjælp af VBNet

  2. Sådan VÆLG FRA gemt procedure

  3. Kan du bruge aggregerede værdier inden for ON DUPLICATE KEY

  4. Tips til at flytte SQL Server-database fra én server til en anden - SQL Tutorial af Rajan Singh