Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: Codeter 08. 03. 2014, 22:40:52
-
Zdravim.
Potrebujem poradit alebo nasmerovat.
Mam klasicky SELECT
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 ?
-
smysl, proc to delat mi trochu unika, ale slo by to asi nejak takhle:
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.
-
...
ak zadam napriklad 123456 ktore sa v DB nenachadza mi vypisalo alterantivy co sa najblizsie podobaju 123456 teda napriklad 12345 ,123457
...
Skus pouzit LIKE:
SELECT NAZOV_S,NAZOV_BEZ FROM xyz WHERE ID LIKE '12345%'
-
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...
-
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ů.
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:
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 (https://demo-1.sql-vyuka.cz/#pruvodce=80&sql=SELECT%09nazev%2C%0A%09rok_vydani%2C%0A%09abs%28rok_vydani%20-%202005%29%20AS%20rozd%C3%ADl%0AFROM%09sbirka.polozka%0AORDER%20BY%20rozd%C3%ADl%0ALIMIT%205%3B).
-
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
-
V tom případě fulltextové vyhledávání.
-
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 ...
-
miesto solru tiez elasticsearch
-
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ů.
-
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,
-
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 ..
-
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.
-
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.
-
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.
-
Apache Lucene je to, co hladas. Funkcne, preskusane, zadarmo.
-
Hugo dik ale websupport to nepodporuje takze tato varianta bohuzial pada
-
Hugo dik ale websupport to nepodporuje takze tato varianta bohuzial pada
To, co chcete, nejde standardními prostředky SQL databází nasimulovat. Je k tomu potřeba fulltextový index – buď jako samostatná aplikace, nebo některé SQL databáze mají rozšíření, která fulltext implementují. Samozřejmě byste si mohl fulltext naprogramovat i sám, ale za prvé by to byla zbytečná práce, za druhé i k tomu potřebujete, aby vám webhosting např. dovolil ukládat soubory (s indexem) na disk.
Takže se podívejte, jestli váš webhosting podporuje fulltextové rozšíření v databázi. Pokud ne, tak si najděte jiný, který to podporovat bude, nebo použijte nějaký VPS, kde si můžete nainstalovat libovolný software.