SQL select s podobným vstupem

Codeter

SQL select s podobným vstupem
« kdy: 08. 03. 2014, 22:40:52 »
Zdravim.

Potrebujem poradit alebo nasmerovat.
Mam klasicky SELECT
Kód: [Vybrat]
SELECT NAZOV_S,NAZOV_BEZ FROM xyz WHERE ID='".$a."'to mi vypise to co potrebujem ale ako to spravit tak aby ak zadam napriklad 123456 ktore sa v DB nenachadza mi vypisalo alterantivy co sa najblizsie podobaju 123456 teda napriklad 12345 ,123457 ,12345 atd atd.
Da sa to riesit cez SQL ?
« Poslední změna: 09. 03. 2014, 20:01:06 od Petr Krčmář »


Petr

Re:SQL select
« Odpověď #1 kdy: 08. 03. 2014, 23:27:10 »
smysl, proc to delat mi trochu unika, ale slo by to asi nejak takhle:
Kód: [Vybrat]
select * from tab where id = (
select case when (select count(*) from tab where id = 666799)=1 then 666799 ELSE NULL end)
union
select * from tab where CAST(id as varchar) like (
select case when (select count(*) from tab where id = 666799)>0 then NULL ELSE '6667%' end);

predpoklada to, ze id je cisleny klic (to neni nutna podminka, stejne se to v tom druhym selektu pretypuje na text) a zaroven primarni nenulovy klic.
To je jenom takova opicarna narychlo, spis jako inspirace, ze i podobny zhuverilosti umi SQL v jedny kvere  ;D Melo by to fungovat v postresu, pretypovani se bude na jinejch DB lisit, na druhou stranu ty asi ani pretypovat nemusis.

mikrom

Re:SQL select
« Odpověď #2 kdy: 09. 03. 2014, 08:48:31 »
...
ak zadam napriklad 123456 ktore sa v DB nenachadza mi vypisalo alterantivy co sa najblizsie podobaju 123456 teda napriklad 12345 ,123457
...

Skus pouzit LIKE:
Kód: [Vybrat]
SELECT NAZOV_S,NAZOV_BEZ FROM xyz WHERE ID LIKE '12345%'

Shin

Re:SQL select
« Odpověď #3 kdy: 09. 03. 2014, 08:55:40 »
Asi bych se podíval jsetli tam je stejnej řádek. Pokud ne, vybral bych jeden menší a jeden větší (nejbližší) a pak bych už asi zbytečně DB netrápil a udělal to někde v aplikaci...

Franta <xkucf03/>

Re:SQL select
« Odpověď #4 kdy: 09. 03. 2014, 09:48:54 »
1) Nauč se dodržovat nějaké konvence – klíčová slova velkými písmeny, identifikátory malými + vhodné odsazování (hlavně u delších dotazů), SQL může být na víc řádků.

Kód: [Vybrat]
SELECT nazov_s, nazov_bez FROM xyz WHERE id = '".$a."'
2) id = '".$a."' je nebezpečná prasárna, kterou bys neměl nikdy napsat – nauč se používat parametrizované dotazy:

Kód: [Vybrat]
SELECT nazov_s, nazov_bez FROM xyz WHERE id = ?
3) Definuj si, co znamená „co nejbližší“ – jestli je to co nejmenší absolutní hodnota rozdílu, tak si to ji jednoduše spočítej, seřaď a omez počet limitem.

Viz příklad na SQL-Výuka.cz.


Codeter

Re:SQL select
« Odpověď #5 kdy: 09. 03. 2014, 11:23:53 »
No ono to je trosku zlozitejsie.
Hrabem sa DB produktov a potrebujem vyhladavat podla mena. Teda klient zada napriklad Samsung Galaxy 4 ale v DB nemusi byt Samsung Galaxy 4 ale len 3. Tych udajov v DB je tak okolo pol mega a menia sa.
Asi to poriesim tak ze v prvom kole si overim ci existuje presny nazov ked to da null osekam jeden znak teda ostane Samsung Galaxy a znova search ak nie tak zasa o jeden menej.
Kazdopadne dakujem za inspiraciu.
Ak mi mal k tomu este niekto co povedat budem len rad

Franta <xkucf03/>

Re:SQL select
« Odpověď #6 kdy: 09. 03. 2014, 11:37:16 »
V tom případě fulltextové vyhledávání.

Mr. Curious

Re:SQL select
« Odpověď #7 kdy: 09. 03. 2014, 11:39:02 »
A co takhle pouzit nejaky seriozni FTS? Treba Apache Solr? Tam muzes priradit ruzne vahy, ruznym vecem ... Treba vetsi vahu shode vyrobce nez nazvu modelu, atp ...

perceptron

Re:SQL select
« Odpověď #8 kdy: 09. 03. 2014, 13:59:49 »
miesto solru tiez elasticsearch

jirka

Re:SQL select
« Odpověď #9 kdy: 09. 03. 2014, 15:34:40 »
rozsekejte názvy produktů na jednotlivá slova a udělejte si z nich index k produktům v jiné tabulce - může to být "samsung","galaxy","samsung galaxy" apod. Když budete osekávat název a hledat možné kombinace, tak budete muset položit spoustu dotazů.

Petr

Re:SQL select
« Odpověď #10 kdy: 09. 03. 2014, 15:53:10 »
No ono to je trosku zlozitejsie.
Hrabem sa DB produktov a potrebujem vyhladavat podla mena. Teda klient zada napriklad Samsung Galaxy 4 ale v DB nemusi byt Samsung Galaxy 4 ale len 3. Tych udajov v DB je tak okolo pol mega a menia sa.
Asi to poriesim tak ze v prvom kole si overim ci existuje presny nazov ked to da null osekam jeden znak teda ostane Samsung Galaxy a znova search ak nie tak zasa o jeden menej.
Kazdopadne dakujem za inspiraciu.
Ak mi mal k tomu este niekto co povedat budem len rad
No, to nevim, jestli to bys nebude chyba uvahy - kdybych si nahodou chtel koupit Samsung Galaxy 4, tak nechapu, proc by vyhledavani melo nabizet i Samsung Galaxy 3, protoze ten asi chtit nebudu. Tohle se spis resi pres vyhledavaci formular, kde das na vyber bud hledani konkretni shody, tj =, nebo pres ten LIKE s tim, ze budes hledat akorat podle prvniho slova.
Nebo elegantejsi reseni pres naseptavac, kdy mu rovnou muzes zobrazit vsechny relevantni vyrobky podle toho, co zacal psat, coz je asi nejjednodussi.
Prohledavat fulltextem nazvy produktu mi neprijde uzitecne, pac je sice hezky, ze to bude vracet miliony zaznamu, ale praktickej  vyznam to asi nebude mit moc velkej,

Mr. Curious

Re:SQL select s podobným vstupem
« Odpověď #11 kdy: 10. 03. 2014, 07:41:35 »
To ze bude vracet miliony vysledku neni pravda. Zalezi jak si nastavi threshold matche ... Kdyz je score mensi nez XXX, tak se vysledky proste nezobrazi ..

ded.kenedy

Re:SQL select s podobným vstupem
« Odpověď #12 kdy: 10. 03. 2014, 11:33:59 »
Pokud tech polozek namas milliony, tak se to resi nasledovne. Vezmes si funkci, ktera urci "podobnost" (vzdalenost) dvou textu:

select * from data order by dist('hledany text', nazec_zbozi) asc;

Kde jako funkci dist pouzijes vhodnou funkci, napr. "Levenshtein distance". Zkus si pripadne pohledat podobne funkce. Problem je, ze toto reseni vyzaduje fulltable scan, tazke je vhodne jen pro relativne mala data.

j

Re:SQL select
« Odpověď #13 kdy: 10. 03. 2014, 14:59:44 »
No ono to je trosku zlozitejsie.
Hrabem sa DB produktov a potrebujem vyhladavat podla mena. Teda klient zada napriklad Samsung Galaxy 4 ale v DB nemusi byt Samsung Galaxy 4 ale len 3. Tych udajov v DB je tak okolo pol mega a menia sa.
Asi to poriesim tak ze v prvom kole si overim ci existuje presny nazov ked to da null osekam jeden znak teda ostane Samsung Galaxy a znova search ak nie tak zasa o jeden menej.
Kazdopadne dakujem za inspiraciu.
Ak mi mal k tomu este niekto co povedat budem len rad

Pokud na to nechces psat expertni system (pripadne nekomu navalit par desitek mega za neco hotovyho), tak potrebujes data. A to takova, ze primo ten, kdo bude pripadne kartu zbozi zakladat, k tomu priradi odpovidajici vztahy na jiny zbozi. Pripadne se to samo resi nejakou kategorii.

Samo, muzes pouzit klasickej fulltext, ale to prevazne moc nefunguje a vraci kraviny. Mno a kde nic (data) neni ... ani ten cert nebere.

Karel

Re:SQL select s podobným vstupem
« Odpověď #14 kdy: 10. 03. 2014, 15:18:23 »
Vnořený select:

  SELECT *
     FROM my_table
   WHERE id = (SELECT max(id)
                       FROM my_table
                      WHERE id <= id_i_look_for)

Ten vnitřní najde nejbližší menší nebo rovno. Najde jeho id. No a pak už je to dotaz jen přes id. Pokud bych chtěl nejbližší vyšší nebo rovno, tak to bude min() a podmínka >=. Pokud chci nejbližší a je to číslo, tak mohu použít:

   SELECT id, abs(id - id_i_look_for) As id_distance
       FROM my_table

Tohle mi vrátí tabulku id, kde u každého je "vzdálenost" od mého. Nad tím:

   SELECT id
      FROM ( ... viz vyse ... )
    WHERE rownum = 1
    ORDER BY id_distance asc

Tohle seradi vysledek podle vzdalenosti a vrati prvni radek (to je to rownum = 1, takhle to dela Oracle, nevim jak jine databaze). Jakmile mam tohle id, tak mohu opet vysledek pouzit jako podminku pro select.