Autor | Zpráva | ||
---|---|---|---|
SteveO Profil * |
#1 · Zasláno: 15. 9. 2015, 14:56:56
Dobrý den,
Mám SQL dotaz: SELECT .... WHERE p.status = 1 AND (SELECT category_id FROM product_to_category ap2c WHERE ap2c.product_id = p.product_id ORDER BY ap2c.product_id DESC LIMIT 1) NOT IN (92) Ten sice funguje, ale ne úplně správně v případě, že k produktu patří více kategorií. Lze to nějak upravit tak, abych mohl ze subquery ostranit limit, vracela by všechny odpovídající kategorie, mezi kterými bych pak hledal ID, která nechci? A také, aby podmínka vyhovovala, i když produkty nepatří do žádné kategorie. Díky. |
||
juriad Profil |
#2 · Zasláno: 15. 9. 2015, 15:14:13
Máš tabulku product a tabulku product_to_category s vazbou 1:N. Chceš produkty, které nejsou v kategorii 92 a mají status 1?
Nechápu vůbec proč tam máš ten ORDR BY a LIMIT. |
||
SteveO Profil * |
#3 · Zasláno: 15. 9. 2015, 15:21:15
Protože v tabulce product_to_category může být:
product_id, category_id 1, 92 ale také: product_id, category_id 2, 92 2, 123 2, 59 nebo: product_id, category_id 3, 50 3, 123 3, 92 Začínám se obávat, že už jsem z toho tak vyfluslej, že řeším kraviny :D |
||
juriad Profil |
#4 · Zasláno: 15. 9. 2015, 15:26:58
SteveO:
Ok, dal jsi nám data, teď nás zajímá, co má být výsledkem dotazu. Proč by mělo záležet na pořadí záznamů v tabulce product_to_category? (Nesmí, databáze pořadí vůbec negarantuje). Ještě jednou tedy: Chceš produkty, které nejsou v kategorii 92 a mají status 1? |
||
SteveO Profil * |
#5 · Zasláno: 15. 9. 2015, 15:29:53
Chceš produkty, které nejsou v kategorii 92 a mají status 1? -> ANO, ale možná bude později potřeba vynechat produkty třeba z 10 kategorií (kategorií jsou stovky).
|
||
juriad Profil |
Skvěle.
SELECT p.* FROM products p LEFT JOIN product_to_category ap2c ON ap2c.product_id = p.product_id AND ap2c.category_id IN (92) WHERE p.status = 1 AND ap2c.product_id IS NULL Toto ke každému produktu přidá kategorii ze seznamu zakázaných. A pak vyfiltrujeme jen ty, u kterých se mu to nepodařilo. Ono to z: product_name, produkt_id, status kalhoty, 1, 1 košile, 2, 1 pantofle, 4, 1 čepice, 5, 1 product_id, category_id 4, 30 4, 29 Napřed vytvoří (připojí záznam o kategorii nebo NULL) *: kalhoty, 1, 1, 1, 92 košile, 2, 1, 2, 92 pantofle, 4, 1, NULL, NULL čepice, 5, 1, NULL, NULL * kdyby ťěch zakázaných bylo víc u jednoho produktu, tady by se oběvily třeba ty kalhoty vícekrát, ale to nevadí, protože v dalším kroku se ty záznamy odstraní. A pak to WHERE podmínka profiltruje na výsledné: pantofle, 4, 1 čepice, 5, 1 Funguje to pro produkty bez kategorií, i produkty s více kategoriemi, produkt může mít dokonce libovolný počet zakázaných kategorí. |
||
SteveO Profil * |
#7 · Zasláno: 15. 9. 2015, 15:54:09
Nemám slov... jednoduché a geniální! Díky moc.
Já to zkoušel i takto: LEFT JOIN product_to_category p2c ON p2c.product_id = p.product_id .. WHERE p2c.category_id NOT IN (92) Ale vracelo mi to i produkty z té vyjmuté kategorie, můžeš mi ještě prosím vysvětlit, proč? |
||
juriad Profil |
SteveO:
Můžu. Tím jsi řekl, že chceš k produktům přidat informaci o kategorii; filtrování WHERE se provádí později. Takže po JOINu vypadají data: kalhoty, 1, 1, 1, 92 košile, 2, 1, 2, 92 košile, 2, 1, 2, 123 košile, 2, 1, 2, 59 pantofle, 4, 1, 4, 30 pantofle, 4, 1, 4, 29 čepice, 5, 1, NULL, NULL A pak se provede ta WHERE podmínka. Výsledek je asi zřejmý: košile, 2, 1, 2, 123 košile, 2, 1, 2, 59 pantofle, 4, 1, 4, 30 pantofle, 4, 1, 4, 29 Tím, že přidáš do té vazební podmínky požadavek na zakázané kategorie děláš to samé jako: SELECT p.* FROM products p LEFT JOIN (SELECT * FROM product_to_category ap2c WHERE ap2c.category_id IN (92)) x ON x.product_id = p.product_id WHERE p.status = 1 AND x.product_id IS NULL V příkladu jsem měl chybu s NULLem (má být v obou posledních sloupcích, nikoli jen v jednom). |
||
SteveO Profil * |
#9 · Zasláno: 15. 9. 2015, 16:12:25
Hmm, ale zde v tvém výsledku WHERE podmínky je to správně, 92 tam není... a já ji tam měl :)
|
||
Časová prodleva: 10 let
|
0