Autor Zpráva
luax
Profil
Mám následující dvě tabulky inzerat a atribut a mezi nimi mám vazební tabulku atributy_inzeratu.



Create table inzerat (
id_inzerat Serial NOT NULL,
nazev_inzeratu Varchar(100) NOT NULL,
primary key (id_inzerat)
) With Oids;

Create table atribut (
id_atribut Serial NOT NULL,
nazev_atributu Varchar(30),
primary key (id_atribut)
) With Oids;


Create table atributy_inzeratu
(
id_inzerat Bigint NOT NULL,
id_atribut Integer NOT NULL,
hodnota_atributu Varchar(30),
primary key (id_inzerat,id_atribut)
) With Oids;




v tabulce atributy_inzerce mám tato data.


13, 6, škoda
13, 7, 100000
13, 8, Benzín
14, 6, ford
14, 7, 200000
14, 8, Benzín



Chci zjistit id_inzerat těch inzerátů, kde je hodnota_atributu = Benzín
a současně je hodnota_atributu škoda a současně má hodnotu_atributu <=500000


Nebo jinak řečeno chci získat id těch inzerátu ve kterých je nabízena škoda která má palivo benzín.
a má najeto méně než 500000 Km

Zkoušel jsem


SELECT DISTINCT inzerat.id_inzerat FROM inzerat
WHERE inzerat.id_inzerat = (
SELECT DISTINCT id_inzerat FROM atributy_inzeratu WHERE hodnota_atributu ='Benzín'
INTERSECT
SELECT DISTINCT id_inzerat FROM atributy_inzeratu WHERE hodnota_atributu ='škoda'
INTERSECT
SELECT DISTINCT id_inzerat FROM atributy_inzeratu WHERE hodnota_atributu <=500000
)
ORDER BY ...


Tenhle dotaz sice vrací správné výsledky ale připadá mi dost komplikovaný
Nevíte jak jej zjednodušit, optimalizovat?

Celá databáze běží na PostgreSQL.

Zkusil jsem se zbavit těch vnořených selectů a vytvořil dotaz



SELECT inzerat.id_inzerat
FROM inzerat, atributy_inzeratu
WHERE inzerat.id_inzerat = atributy_inzeratu.id_inzerat
AND atributy_inzeratu.hodnota_atributu = 'Benzin'
AND atributy_inzeratu.hodnota_atributu = 'škoda'
AND atributy_inzeratu.hodnota_atributu <= 500000


Ten mi ale nic nevrací.
Jan Němec
Profil
Ahoj

To je jasne, ze ti nebude fungovat ten spodni dotaz. Protoze ty data v tabulce atributy_inzerat podle te spodni podminky museli bejt v jednom řadku kterej by ti splňoval tuto podminky. Pokud to dělas tim vnořenym selektem tak pak teprve ti to vraci nějaky zaznamy protože vytvařís pole ID ve kterém hledas.

Teda podme me pokud ma nekdo jinej dotaz rad budu diskutovat :)
Kajman_
Profil *
Otázkou je, pro koho chcete optimalizovat. Pokud pro db, tak bych si tipnul, že ten původní dotaz bude to pravé. Možná bych do dotazu ještě přidal podmínku na id_atributu - to by to zrychlit mohlo.

V druhé variantě je třeba spojit první tabulku s třemi pojmenováními tabulky druhé.
Anonymní
Profil *
Možná mi něco uniká, ale proč základ dělíš do třech tabulek?

Tiše předpokládám, že 1auto=1 inzerát

Stačí jedna tabulka
INZERAT
id_inzeratu, prodej_nakup, nazev, datum_podani, zadavatel, region,...... , vyrobce_auta, rok_vyroby, cena, palivo, popis .....

Dál bych nadefinoval číselníky
např. REGION
id_regionu, region

VYROBCE_AUTA
id_vyrobce, vyrobce

a možná i další číselníky
Tomu bych následně přizpůsobil i tabulku INZERAT
region nahradil id_regionu atd.
luax
Profil
díky všem za rady, zkusím ještě tu možnost s třemi pojmenováními tabulky a uvidím, co bude rychlejší
Anonymní
Profil *
iMožná mi něco uniká, ale proč základ dělíš do třech tabulek?

Kdybych věděl hned od začátku jaké bude mít inzerce kategorie, jaké budou atributy u inzerátů, jaké budou číselníky, a podle jakých hodnot může uživatel v dané kategorii vyhledávat, tak bych nic do třech tabulek nedělil. (taky to tak ze začátku bylo) Jenomže zadavatel mi každou chvíli telefonuje že chce přidat tohle a vyhledávat ještě podle tohoto, ... Takže jsem celou aplikaci postavil tak, že si zadavatel sám zadává číselníky, kategorie, sám si určuje podle jakých parametrů se v dané kategorii bude vyhledávat ... Bohužel to vede na trošku složitější SQL dotazy.
mig
Profil *
Ale to je docela logické a správné! Číselníky by si měl naplnit a udržovat zadavatel.
Je čistě na něm zda bude chtít hledat auta podle výrobců, nebo i podle typů (fabia, oktávka ...)
On by měl jasně specifikovat co všechno od toho očekává.

Na tobě je, udělat vše max. flexibilní s výhledem na další rozšiřitelnost a právě k tomu slouží i ty číslelníky.
Toto téma je uzamčeno. Odpověď nelze zaslat.