sql >> Databasteknik >  >> RDS >> Mysql

Markera alla där fältet innehåller sträng separerade med kommatecken

Med MySQL kan du använda 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

Observera att FIND_IN_SET förväntar sig att strängar är komma separerade, inte komma och blanksteg separerat. Så du kan ha problem med den sista taggen. Det verkligen bästa sättet vore att normalisera tabellen; annars kan du ta bort mellanslag från tags kolumn; slutligen kan du komma runt problemet genom att lägga till ett mellanslag i tags kolumn:

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

Om antalet taggar är begränsat kan du överväga att konvertera kolumnen till en SET . Detta kommer att förbättra effektiviteten avsevärt.

UPPDATERA

Förutom att jag fick mellanslag fel . De är före strängarna och inte efter.

Så:

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

Men återigen, bli av med dessa utrymmen - de är inget annat än problem :-)

UPPDATERING 2

Ovanstående fungerar, okej. Men det är nästan allt du kan säga till min fördel. Lösningen är inte bara ganska *in*effektiv, den gör också systemet nästan omöjligt att underhålla (been there, done that, fick T-shirten och en uttuggad rumpa under densamma). Så jag ska nu harpa lite för normalisering, d.v.s. att ha åtminstone dessa två fler tabeller:

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 );

Hur mycket är detta bättre? Låt mig räkna vägarna.

  • du kan enkelt lägga till mer flexibla frågor ("har alla taggar i iOS, C++, ..." eller "har minst tre taggar bland dessa:( iOS, Python, SQL, .NET, Haskell )". Ja, du kan göra detta med FIND_IN_SET , men tro mig, du kommer inte att njuta av det .
  • du har en kontrollerad ordbok av taggar, vilket ger dig möjlighet att kontrollera om någon tagg är känd (såväl som enkelt generera listor som kombinationsrutor eller -- sa någon "jQuery Autocomplete"?).
  • sparar en del diskfastigheter (taggar skrivs en gång)
  • sökningar är snabba . Om du redan känner till taggarna du letar efter och förkompilerar dem till tagg-ID:n kommer de att lämna SQL-gummibrännmärken på trottoaren när de körs (indexerad sökning efter ett heltal värde!). Och taggar som inte kommer att kompileras kommer inte att finnas där , och du kommer att veta detta redan innan sökningen startar.
  • gör det mycket lättare att byta namn på taggar
  • kan innehålla valfritt nummer av taggar (du riskerar att få någon tagg trunkerad till 'iOS Developm' förr eller senare...)

Jag tror att "CSV-fältet" är censerat(eller)erat bland SQL-antimönster ( http://pragprog.com/book/bksqla/sql-antipatterns ), och av goda skäl.



  1. Uppdatera mysql-tabellen var tjugofyra timme automatiskt

  2. Betydelse av id =LAST_INSERT_ID(id)

  3. Hur gör man skiftlägesokänslig fråga i Postgresql?

  4. Använder du Cassandra istället för memcache?