sql >> Database >  >> RDS >> Mysql

Alles selecteren waar het veld een tekenreeks bevat, gescheiden door een komma

Met MySQL kunt u FIND_IN_SET() . gebruiken :

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

Merk op dat FIND_IN_SET verwacht dat strings komma zijn gescheiden, niet komma en spatie uit elkaar gehaald. U kunt dus problemen hebben met de laatste tag. De beste manier zou zijn om de tabel te normaliseren; anders zou je spaties uit de tags kunnen verwijderen kolom; ten slotte kunt u het probleem omzeilen door een spatie toe te voegen aan de tags kolom:

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

Als het aantal tags beperkt is, kunt u overwegen de kolom te converteren naar een SET . Dit zal de efficiëntie aanzienlijk verbeteren.

UPDATE

Alleen heb ik de spaties fout . Ze zijn voor de snaren en niet erna.

Dus:

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

Maar nogmaals, doe die spaties weg - het zijn alleen maar problemen :-)

UPDATE 2

Bovenstaande werkt, oké. Maar dat is bijna alles wat je in mijn voordeel kunt zeggen. Niet alleen is de oplossing behoorlijk *in*efficiënt, het maakt het systeem ook bijna onhoudbaar (been there, done that, heb het T-shirt en een uitgekauwde kont eronder). Dus ik zal nu een beetje pleiten voor normalisatie, d.w.z. met ten minste deze twee extra tabellen:

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

Hoeveel is dit beter? Laat me de manieren tellen.

  • u kunt eenvoudig flexibelere zoekopdrachten toevoegen ("heeft alle tags in iOS, C++, ..." of "heeft minstens drie tags:(iOS, Python, SQL, .NET, Haskell )". Ja, je kunt dit doen met FIND_IN_SET , maar geloof me, je zal er niet van genieten .
  • je hebt een gecontroleerd woordenboek van tags, waarmee u kunt controleren of een tag bekend is (en ook gemakkelijk lijsten kunt genereren zoals vervolgkeuzelijsten met invoervak, of -- zei iemand 'jQuery Autocomplete'?).
  • bespaart wat schijfruimte (tags worden eenmaal geschreven)
  • zoekopdrachten zijn snel . Als je de tags die je zoekt al kent en ze vooraf compileert in tag-ID's, zullen ze tijdens het hardlopen SQL-rubberen schroeiplekken op de stoep achterlaten (geïndexeerde zoekopdracht voor een integer waarde!). En tags die niet compileren zullen er niet zijn , en u weet dit zelfs voordat het zoeken begint.
  • maakt het veel gemakkelijker om tags te hernoemen
  • kan elk nummer bevatten van tags (u loopt het risico dat een tag vroeg of laat wordt afgekapt tot 'iOS Developm'...)

Ik geloof dat het "CSV-veld" wordt gecensureerd (of) onder de SQL-antipatronen ( http://pragprog.com/book/bksqla/sql-antipatterns ), en met een goede reden.



  1. Hoe een json-kolom opvragen voor lege objecten?

  2. Manieren om verwijderde database bij te houden in SQL Server

  3. Problemen met SQL Server CPU-prestaties oplossen

  4. Samenvoegen tussen tabellen in twee verschillende databases?