abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
eParkomat, startup z ČR, postoupil mezi finalisty evropského akcelerátoru ChallengeUp!
Robot na pivo mu otevřel dveře k opravdovému byznysu
Internet věcí: Propojený svět? Už se to blíží...
včera 16:24 | Nová verze

Byla vydána Mageia 5.1. Jedná se o první opravné vydání verze 5, jež vyšla v červnu loňského roku (zprávička). Uživatelům verze 5 nepřináší opravné vydání nic nového, samozřejmě pokud pravidelně aktualizují. Vydání obsahuje všechny aktualizace za posledního téměř půldruhého roku. Mageia 5.1 obsahuje LibreOffice 4.4.7, Linux 4.4.32, KDE4 4.14.5 nebo GNOME 3.14.3.

Ladislav Hagara | Komentářů: 0
včera 13:42 | Pozvánky

V Praze probíhá konference Internet a Technologie 16.2, volné pokračování jarní konference sdružení CZ.NIC. Konferenci lze sledovat online na YouTube. K dispozici je také archiv předchozích konferencí.

Ladislav Hagara | Komentářů: 0
2.12. 22:44 | Komunita

Joinup informuje, že Mnichov používá open source groupware Kolab. V srpnu byl dokončen dvouletý přechod na toto řešení. V provozu je asi 60 000 poštovních schránek. Nejenom Kolabu se věnoval Georg Greve ve své přednášce Open Source: the future for the European institutions (SlideShare) na konferenci DIGITEC 2016, jež proběhla v úterý 29. listopadu v Bruselu. Videozáznam přednášek z hlavního sálu je ke zhlédnutí na Livestreamu.

Ladislav Hagara | Komentářů: 16
2.12. 15:30 | Zajímavý projekt

Společnost Jolla oznámila v příspěvku Case study: Sailfish Watch na svém blogu, že naportovala Sailfish OS na chytré hodinky. Využila a inspirovala se otevřeným operačním systémem pro chytré hodinky AsteroidOS. Použita je knihovna libhybris. Ukázka ovládání hodinek na YouTube.

Ladislav Hagara | Komentářů: 8
2.12. 14:15 | Nová verze

Byla vydána verze 7.1.0 skriptovacího jazyka PHP používaného zejména k vývoji dynamických webových stránek. Jedná se o první stabilní verzi nejnovější větvě 7.1. Přehled novinek v dokumentaci. Podrobnosti v ChangeLogu. K dispozici je také příručka pro přechod z PHP 7.0.x na PHP 7.1.x.

Ladislav Hagara | Komentářů: 2
2.12. 12:55 | Nová verze

Google Chrome 55 byl prohlášen za stabilní. Nejnovější stabilní verze 55.0.2883.75 tohoto webového prohlížeče přináší řadu oprav a vylepšení (YouTube). Opraveno bylo také 36 bezpečnostních chyb. Mariusz Mlynski si například vydělal 22 500 dolarů za 3 nahlášené chyby (Universal XSS in Blink).

Ladislav Hagara | Komentářů: 4
2.12. 11:55 | Pozvánky

Máte rádi svobodný software a hardware nebo se o nich chcete něco dozvědět? Přijďte na 135. sraz spolku OpenAlt, který se bude konat ve čtvrtek 8. prosince od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5). Sraz bude tentokrát tématický. Bude retro! K vidění budou přístroje jako Psion 5mx nebo Palm Z22. Ze svobodného hardwaru pak Openmoko nebo čtečka WikiReader. Přijďte se i vy pochlubit svými legendami, nebo alespoň na pivo. Moderní hardware má vstup samozřejmě také povolen.

xkucf03 | Komentářů: 0
2.12. 00:10 | Nová verze

Byla vydána verze 3.2 svobodného systému pro detekci a prevenci průniků a monitorování bezpečnosti počítačových sítí Suricata. Z novinek lze zmínit například podporu protokolů DNP3 a CIP/ENIP, vylepšenou podporu TLS a samozřejmě také aktualizovanou dokumentaci.

Ladislav Hagara | Komentářů: 0
1.12. 21:00 | Nová verze

Byla vydána beta verze Linux Mintu 18.1 s kódovým jménem Serena. Na blogu Linux Mintu jsou hned dvě oznámení. První o vydání Linux Mintu s prostředím MATE a druhé o vydání Linux Mintu s prostředím Cinnamon. Stejným způsobem jsou rozděleny také poznámky k vydání (MATE, Cinnamon) a přehled novinek s náhledy (MATE, Cinnamon). Linux Mint 18.1 bude podporován až do roku 2021.

Ladislav Hagara | Komentářů: 0
1.12. 16:42 | Nová verze

Byl vydán Devuan Jessie 1.0 Beta 2. Jedná se o druhou beta verzi forku Debianu bez systemd představeného v listopadu 2014 (zprávička). První beta verze byla vydána v dubnu letošního roku (zprávička). Jedna z posledních přednášek věnovaných Devuanu proběhla v listopadu na konferenci FSCONS 2016 (YouTube, pdf).

Ladislav Hagara | Komentářů: 0
Kolik máte dat ve svém domovském adresáři na svém primárním osobním počítači?
 (32%)
 (24%)
 (29%)
 (7%)
 (5%)
 (3%)
Celkem 767 hlasů
 Komentářů: 50, poslední 29.11. 15:50
Rozcestník
Reklama

Dotaz: MySQL vicenasobny AND nad jednim sloupcem

5.4.2012 16:39 mejvas
MySQL vicenasobny AND nad jednim sloupcem
Přečteno: 801×
Ahoj, mohl by nejaky databazovy specialista poradit s nasledujicim problemem? Snazim se ho vyresit bez uspechu uz druhy den.

Vytvarim dotaz, kdy chci ziskat vypis clanku, ktere jsou pouze ve specifickych kategoriich. Zjednodusene receno

SELECT * FROM `table` WHERE `categ`=X AND `categ`=Y AND `categ`=Z

Problem je, ze MySQL v tomto pripade nic nevrati, i kdyz by mel. Pri googlovani a prohledavani ruznych diskuzi narazim pouze na radu pouzit kontrukci IN tedy `categ` IN (X,Y,Z) Nicmene to neni reseni, protoze konstrukce IN reprezuntuje operator OR nikoliv AND. Tedy vrati i zaznamy, ktere jsou pouze v jedne ze zadanych kategorii.

Vi nekdo jak to resit?

Konkretni pripad. Chci ve wordpressu zobrazit clanky, ktere musi byt ve trech ruznych kategoriich zaroven.

query s pouzitim IN, ktera to neresi SELECT p.* FROM wp_posts AS p JOIN wp_term_relationships AS tr ON p.ID = tr.object_id JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE p.post_status IN ('publish') AND p.post_type IN ('post') AND tt_term_id IN(23,48,52) AND tt.taxonomy IN ('category' , 'post_tag') GROUP BY p.ID ORDER BY p.post_date desc

Budu vdecny za kazde nakopnuti...


Řešení dotazu:


Odpovědi

5.4.2012 17:28 kuka
Rozbalit Rozbalit vše Re: MySQL vicenasobny AND nad jednim sloupcem
Ze ten zjednoduseny dotaz nic nevrati je zcela v poradku a je to videt na prvni pohled - tezko se muze nejaka hodnota rovnat zaroven X i Y. Lze pouzit napr. exists ve smyslu existuje zarazeni do kategorie X a zaroven existuje i zarazeni do kategorie Y atd.
5.4.2012 20:18 deadmail
Rozbalit Rozbalit vše Re: MySQL vicenasobny AND nad jednim sloupcem
Zavisi od toho ako je ulozene v tej tabulke ... Ak je tam pre jeden clanok patriaci do viacerych kategorii niekolko zaznamov-riadkov (t.j. tabulka clanky_kateg obsahuje dva stlpce (clanok_id, kateg) a zaznamy napr. (clanok5, x), (clanok5, y), (clanok5, z)), tak by mohlo fungovat nieco taketo:
SELECT clanok_id 
FROM (SELECT clanok_id FROM clanky_kateg WHERE kateg="x") AS tbl_x 
JOIN (SELECT clanok_id FROM clanky_kateg WHERE kateg="y") AS tbl_y USING (clanok_id)
JOIN (SELECT clanok_id FROM clanky_kateg WHERE kateg="z") AS tbl_z USING (clanok_id)
6.4.2012 14:57 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MySQL vicenasobny AND nad jednim sloupcem
Tím jste ale jen složitě nahradil IN nebo OR.
6.4.2012 14:59 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MySQL vicenasobny AND nad jednim sloupcem
Eh, pardon, kecám. Viděl jsem tam nevím kde UNION…
6.4.2012 15:10 Filip Jirsák | skóre: 66 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: MySQL vicenasobny AND nad jednim sloupcem
Pokud to chcete řešit univerzálním parametrizovaným dotazem (tj. nepřidávat tolik JOINů, kolik je kategorií), mělo by to jít udělat tak, že v subselectu načtete všechny kategorie daného článku, které patří do požadovaných kategorií (pomocí IN), a pak porovnáte počet požadovaných kategorií s počtem záznamů tohoto subselectu.
SELECT clanek_id 
FROM clanky
WHERE (
  SELECT COUNT(DISTINCT kategorie_id)
  FROM kategorie
  JOIN clanek_kategorie ...
  WHERE kategorie_nazev IN (?)
) = ?;
V prvním parametru pak bude seznam požadovaných kategorií, v druhém jejich počet.
8.4.2012 16:39 l0gik | skóre: 22
Rozbalit Rozbalit vše Re: MySQL vicenasobny AND nad jednim sloupcem
Myšlenka dobrá, ale...
  • V tom subselectu zchází "vazební" podmínka na parent table.
  • Pokud by tam byla, jde o subselect vázanej na každou řádku, takže je to hrozně pomalý.
  • Proč DISTINCT kategorie_id? (když už distinct, tj. předpokládám možnost duplicitních kategorií jednoho článku, tak snad kategorie_nazev, ne - kategorie_id bude tak jako tak unikátní)

    Přitom by úplně stačilo:
    
    SELECT clanek_id FROM kategorie 
    WHERE kategorie_nazev IN (...)
    GROUP BY clanek_id
    HAVING COUNT(DISCTINCT kategorie_nazev) = ...
    Popř. pokud bychom chtěli celej článek, tak to obalit SELECT * FROM clanek WHERE clanek_id IN (..dotaz výše..).

    Jinak pokud není výsledkem skoro celá tabulka článků, tak je řešení s JOIN IMHO lepší, protože to umožní využít indexy. Todle IMHO nutně projde všechny články, i když ve výsledku jich bude jen pár a i když by třeba v jedné kategorii žádný článek nebyl.

    To, co tady chceme po databázi je vlastně průnik množin. A to je prostě INNER JOIN. Opisovat to jinak sice jde, ale většinou je lepší optimalitzaci nechat na databázi, než ji vnucovat nějakou svoji. Vygenerovat ty inner joiny programovým kódem je triviální. SQL je ukecanej jazyk, krátkej zápis ještě nemusí znamenat, že je optimální.
  • 8.4.2012 17:08 Filip Jirsák | skóre: 66 | blog: Fa & Bi
    Rozbalit Rozbalit vše Re: MySQL vicenasobny AND nad jednim sloupcem
    Dotaz na kategorie článku se stejně musí vždy provést, ať už bude mít formu subselectu nebo jinou. Distinct pro případ, že by článek měl jednu kategorii přiřazenou vícekrát. Řešení s GROUP BY má tu nevýhodu, že takhle vytáhnete jen ID článků -- předpokládám, že ve skutečnosti budou potřeba i další údaje, takže by bylo nutné výsledek tohoto dotazu použít v dalším dotazu na ostatní hodnoty.

    Souhlasím, že INNER JOINy budou pro databázi průhlednější, ale dotaz je pak závislý na vstupních datech a teoreticky při velkém počtu požadovaných kategorií může být problém s počtem JOINů.
    8.4.2012 17:36 l0gik | skóre: 22
    Rozbalit Rozbalit vše Re: MySQL vicenasobny AND nad jednim sloupcem
  • Jo, jenže závislé subselekty se dělají pro každý řádek zvlášť, zatímco GROUPBY se provede jednou pro všechny. Někdy si pravda databáze závislý subselect zoptimalizuje, ale spoléhat se na to nedá a u dotazu s COUNT obzvlášť ne. Navíc pokud si ten subselect databáze zoptimalizuje, tak právě do formy toho GROUPBY.
  • Jo, jenže na vyloučení duplicit kategorií je Ti DISCTINCT kategorie_id na nic, protože kategorie_id je PK a tedy unikátní by definition. Na výsledek tedy DISTINCT žádnej vliv nemá. To bys tam musel mít count(DISTINCT kategorie_nazev).... Jak píšu už v předešlym postu.
  • Tak dáš group by do subselectu a vytáhneš si k tomu zbytek z tabulky článků, vždyť to tam taky píšu. Pořád to ale bude výkonem někde jinde, než spešl selekt pro každou řádku z článků.
  • Problém s počtem joinů? To by musel bejt jó velkej počet kategorií, aby se to nevyplatilo. Takovýdle dotazy se dělaj většinou ve filtrech se vstupem užíváka, takže to myslím nehrozí.
  • 8.4.2012 18:01 Filip Jirsák | skóre: 66 | blog: Fa & Bi
    Rozbalit Rozbalit vše Re: MySQL vicenasobny AND nad jednim sloupcem
    Jo, jenže na vyloučení duplicit kategorií je Ti DISCTINCT kategorie_id na nic, protože kategorie_id je PK a tedy unikátní by definition. Na výsledek tedy DISTINCT žádnej vliv nemá. To bys tam musel mít count(DISTINCT kategorie_nazev)....
    DISTINCT neřeší duplicity názvů v tabulce kategorií, ale duplicitu přiřazení kategorií k článkům. Pokud by v mapovací tabulce byly duplicitní záznamy, přes JOIN by se dostaly i do výsledné sady a pak by COUNT neseděl.
    clanek_id | kategorie_id
    ----------+-------------
            1 |            1
            1 |            2
            1 |            2   -- duplicita!
            2 |            3
    
    Lepší řešení je samozřejmě unikátní index na clanek_id+kategorie_id, ale DISTINCT podle mne v tomto případě skoro nic nestojí a ten kód nebyl v žádném případě hotový jen ho zkopírovat a použít, byl myšlen jen jako náčrt, který by si tazatel musel dodělat.
    8.4.2012 19:34 l0gik | skóre: 22
    Rozbalit Rozbalit vše Re: MySQL vicenasobny AND nad jednim sloupcem
    Jo takhle, ty tam máš join a dvě tabulky, to jsem přehlíd, pak to tak je: tím, žes vypustil ON a v tom distinct nekvalifikoval (což bys s joinem musel) jsem předpkládal, že je to jednodušší a blbější struktura, kdy ve vazební tabulce je rovnou název kategorie, pak by naopak byl potřeba distinct na ten název a ne na id, takhle je to dobře.

    Nicméně ostatní výtky, hlavně ta, že dělat pro každou řádku subselect, trvají, todle je jen detail.
    5.4.2012 22:10 Dejv | skóre: 36 | blog: Jak ten blog nazvat ... ? | Ostrava
    Rozbalit Rozbalit vše Re: MySQL vicenasobny AND nad jednim sloupcem

    SELECT *
    FROM `table`
    WHERE `categ`=X
       AND `categ`=Y
       AND `categ`=Z
    fungovat nemuze, jak uz bylo vyse zmineno i vysvetleno.

    select t.idclanku, t.navezclanku...
    from table t
       inner join categ c1 on c1.idclanku=t.idclanku and c1.cat='X'
       inner join categ c2 on c2.idclanku=t.idclanku and c2.cat='Y'
       inner join categ c3 on c3.idclanku=t.idclanku and c3.cat='Z'
    where
       t.idclanku=...
    sice (asi) neni nejvhodnejsi z hlediska vykonu, ale fungovat by mohlo. Akorat mozna bude potreba zmenit ty joiny ma nejake left nebo right outer.

    Pevne verim, ze zkusenejsi uzivatele me s mymi napady usmerni a poslou tam, kam tyto napady patri...
    8.4.2012 16:48 l0gik | skóre: 22
    Rozbalit Rozbalit vše Re: MySQL vicenasobny AND nad jednim sloupcem
    INNER JOINY jsou dobře a naopak je to z hlediska výkonu to nejlepší. Protože to nechává optimalizaci na databázi. Pokud bude výsledkem +- celá tabulka, tak si to vybere nejmenší, ostatní zahašuje a tu nejmenší projede. Bude to stát cca N, takže pohoda.

    Pokud bude alespoň jedna kategorie malá, tak to IMHO vybere její záznamy a ověří, že jsou i v ostatních kategoriích. Opět nejlepší postup.

    Ostatní zde nabízené postupy donutí databázi ke konkrétnímu plánu, což může být někdy ten nejlepší, ale v jiné situaci katastrofa.
    8.4.2012 16:51 l0gik | skóre: 22
    Rozbalit Rozbalit vše Re: MySQL vicenasobny AND nad jednim sloupcem
    INNER JOINY jsou dobře a naopak je to z hlediska výkonu to nejlepší. Protože to nechává optimalizaci na databázi. Pokud bude výsledkem +- celá tabulka, tak si to vybere nejmenší, ostatní zahašuje a tu nejmenší projede. Bude to stát cca N, takže pohoda, ostatní nabízené postupy na tom nebudou lépe.

    Pokud bude alespoň jedna kategorie malá, tak to IMHO vybere její záznamy a ověří, že jsou i v ostatních kategoriích. Opět nejlepší postup.

    Ostatní zde nabízené postupy donutí databázi ke konkrétnímu plánu, což sice může být někdy ten nejlepší, ale v jiné situaci katastrofa.
    7.4.2012 09:56 Semo | skóre: 44 | blog: Semo
    Rozbalit Rozbalit vše Re: MySQL vicenasobny AND nad jednim sloupcem
    Na denormalizaciu chces pouzit operator GROUP_CONCAT(expr).

    Takze asi nieco ako
    SELECT clanok_id, ','||group_concat(categ)||',' as allcat
    FROM table
    GROUP BY clanok_id
    HAVING allcat LIKE '%,X,%'
        AND allcat LIKE '%,Y,%'
        AND allcat LIKE '%,Z,%'
    ;
    Pisem to z hlavy a zijem na inej databaze, takze mozno nieco z toho bude treba zapisat v MySQL inak, ale asi by to malo chodit.
    If you hold a Unix shell up to your ear, you can you hear the C.
    rADOn avatar 7.4.2012 19:18 rADOn | skóre: 44 | blog: bloK | Praha
    Rozbalit Rozbalit vše Re: MySQL vicenasobny AND nad jednim sloupcem
    Tohle může krásně fungovat pro pět a půl řádku, ale ne nad většími daty. Efektivně jsi vyřadil možnost použít jakýkoliv index.
    "2^24 comments ought to be enough for anyone" -- CmdrTaco

    Založit nové vláknoNahoru

    Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

    ISSN 1214-1267   www.czech-server.cz
    © 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.