sql >> Databáze >  >> RDS >> Mysql

Hodnoty oddělené čárkami v klauzuli MySQL IN

Na základě příkladu FIND_IN_SET() od @Jeremy Smith to můžete udělat pomocí spojení, takže nemusíte spouštět poddotaz.

SELECT * FROM table t
JOIN locations l ON FIND_IN_SET(t.e_ID, l.city) > 0
WHERE l.e_ID = ?

Je známo, že tato funkce funguje velmi špatně, protože musí provádět skenování tabulek a vyhodnocovat funkci FIND_IN_SET() pro každé kombinace řádků v table a locations . Nemůže používat index a neexistuje způsob, jak jej zlepšit.

Vím, že jste řekl, že se snažíte co nejlépe využít špatný návrh databáze, ale musíte pochopit, jak drasticky špatné to je.

Vysvětlení:Předpokládejme, že bych vás chtěl požádat, abyste vyhledali každého v telefonním seznamu, jehož první, střední nebo poslední iniciála je "J." Seřazené pořadí knihy v tomto případě nijak nepomůže, protože stejně musíte skenovat každou jednotlivou stránku.

LIKE řešení poskytnuté @fthiella má podobný problém, pokud jde o výkon. Nelze jej indexovat.

Podívejte se také na mou odpověď na Je ukládání seznamu s oddělovači ve sloupci databáze opravdu tak špatné? pro další úskalí tohoto způsobu ukládání denormalizovaných dat.

Pokud můžete vytvořit doplňkovou tabulku pro uložení rejstříku, můžete namapovat umístění ke každému záznamu v seznamu měst:

CREATE TABLE location2city (
 location INT,
 city INT,
 PRIMARY KEY (location, city)
); 

Za předpokladu, že máte vyhledávací tabulku pro všechna možná města (nejen ta uvedená v table ) můžete snést neefektivnost při vytváření mapování:

INSERT INTO location2city (location, city)
  SELECT l.e_ID, c.e_ID FROM cities c JOIN locations l
  ON FIND_IN_SET(c.e_ID, l.city) > 0;

Nyní můžete spustit mnohem efektivnější dotaz k nalezení položek ve vaší table :

SELECT * FROM location2city l
JOIN table t ON t.e_ID = l.city
WHERE l.e_ID = ?;

To může využít index. Nyní se musíte postarat o to, aby jakékoli INSERT/UPDATE/DELETE řádků v locations také vloží odpovídající řádky mapování do location2city .



  1. Žádné mapování dialektu pro typ JDBC:2003

  2. Příklady TIME() – MySQL

  3. LIKE vs CONTAINS na SQL Server

  4. Jak odstranit úvodní nuly z dat v Oracle