Autor Zpráva
quatzael
Profil
Lze nějak použít přímo hodnotu ze sloupce jako součást názvu tabulky pro JOIN v tom samém dotazu?

Příklad tabulky:

|=====   contracts   =====|
| id | category |   type  |
|-------------------------|
| 1 |     x     |   aaa   |
| 2 |     y     |   bbb   |

SQL dotaz:

 SELECT * 
 FROM contracts
 JOIN contracts_detail_{contracts.type} ON contracts.id = contracts_detail_{contracts.type}.contract_id 

Prostě nějak to sestavit, aby z toho dotazu bylo zřejmé, že {contracts.type} má vrátit např. hodnotu "aaa" a bylo by to pro odpovídající řádek:
JOIN contracts_detail_aaa ... nebo JOIN contracts_detail_bbb ... ?

Případně jestli je to nemožné takto, jestli by to šlo, alespoň vyřešit nějakou IF podmínkou? Něco jako:

SELECT * 
 FROM contracts
 IF contracts.type == 'aaa'
 JOIN contracts_detail_aaa ON contracts.id = contracts_detail_aaa contract_id 
 IF contracts.type == 'bbb'
 JOIN contracts_detail_bbb ON contracts.id = contracts_detail_bbb contract_id 
 
TomášK
Profil
Ne, nelze. Ani podmínkou.
quatzael
Profil
TomášK:
Jsi si tím opravdu 100% jistej? Zkouším hledat nějaké řešení a vypadá to, že by to mohlo jít nějak pomocí CREATE FUNCTION deklarace.. Opravdu nevím.. Potřebuju, aby to ale fungovalo pro MySQL.
TomášK
Profil
Nejvíc se tomu dokážeš přiblížit, když uděláš proceduru, ve které provedeš první dotaz, ze kterého vybereš názvy sloupců, pak sestavíš ten druhý dotaz jako řetězec a pomocí PREPARE a EXECUTE ho provedeš. Akorát nevím, jestli už MySQL umí vracet z procedur result set, dřív to nešlo. Ale stejně to není řešení, které bych chtěl někde použít.
Tomášeek
Profil
quatzael:
Potřebuju, aby to ale fungovalo pro MySQL.
Myslím, že doopravdy nepotřebuješ, jen si to myslíš. Vypadá to na chybný návrh databáze.
quatzael
Profil
Tomášeek:
Potřebuju to. Návrh databáze možná není ideální, ale o moc lépe to udělat nelze, vzhledem ke specifičnosti jednotlivých kategorií to prostě potřebuju takto. Jinak by tam byly tabulky se stovkami sloupců, ze kterých by se reálně využívaly vždy jen několik.
Kajman
Profil
A proč ty detailní vlastnosti neukládáte do univerzální tabulky, kde jedna vlastnost je na jednom řádku?
quatzael
Profil
Kajman:
O tom píšu, to bych potom měl univerzální tabulku se stovkama sloupců, z nichž bych na každým řádku využil jenom pár..
V tabulce contracts potřebuju souhrnně evidovat všechny smlouvy a ke každý smlouvě potřebuju potom ukládat a získávat info o konkrétním produktu na smlouvě. Jelikož je každý produkt natolik specifický, že potřebuju ukládat u každého z větší části úplně jiná data, tak prostě potřebuju takovéto řešení, ža na každý produkt je jiná tabulka, která vyhovuje jeho konkrétním vlastnostem.
Kajman
Profil
Sloupce by byly přeci jen tři (id_smlouvy, id_vlastnosti, hodnota_vlastnosti) a pro uložení 20 vlastností by v této tabulce bylo k jedné smlouvě 20 řádků.
quatzael
Profil
Kajman:
Jenže těch vlastností je spousta a různý typy. Co tam mám dát za typ dat u slopuce, když tam budu mít v těch vlastnostech ceny, datumy, popisky? Jak potom setřídím záznamy podle určité vlastnosti, která obsahuje datum a čas, když tam budu mít například varchar?
Tomášeek
Profil
quatzael:
Datum bude uvedeny v tabulce contracts. Neni důvod mit jej mimo, v tabulce "vlastnosti".

Ceny (pokud je to částka na fakture, jedna, celková), bude tamtéž.

Pokud budes ukládat jednotlive položky, pak do tabulky items | contract_id, item(_id), price (+ volitelné amount, atd.).
Kajman
Profil
Občas se pro hodnotu dynamických atributů používá více sloupců (řetězec, číslo, datum) a jedno z nich se vyplňuje. Aplikace podle číselníku vlastností bude vědět, který sloupec použít pro ukládání či zobrazení.

Ale základní vlastnosti, které má většina položek (cena, měna, datum) mohou přeci zůstat v hlavní tabulce, jak píše Tomášeek.
quatzael
Profil
Tomášeek:
To jsi špatně pochopil, snažím se tady už několikrát vysvětlit, že jde o specifické vlastnosti jednotlivých produktů. Nejde jen o datum vložení záznamu, počátku smlouvy apod., ale o různé datumy událostí, které se vyskytují jen u některých produktů a u jiných nejsou nebo jde zase o datumy jiných registrací apod.
Řešením by mohlo být to co píše Kajman (řetězec, číslo, datum), ale možná jsem napsal špatně, že jde u každého produktu jen o pár záznamů.
Ve skutečnosti má každý produkt něco přes 100 vlastností, které potřebuju ukládat a kolem 80% z toho je specifických. Navíc jednotlivý souhrnný vlastnosti, který se vyskytují u více produktů, ukládám ještě do dalších podtabulek, takže celý je to hodně složitý.

Kdybych to dělal jak navrhujete, tak místo vkládání jednoho řádku do cca 5 tabulekh budu vkládat do jedný tabulky 100 řádků.. To je přece nesmysl. Až tam budu mít 10 tis. smluv, tak tam budu mít přes milion záznamů. To nevím jak potom bude fungovat ten SELECT, když bude tahat 100 záznamů z milionu podle id_smlouvy..


Když se tady ptám na nějaké konkrétní řešení, tak to znamená, že potřebuju opravdu to dané řešení. Já nevytvářím nějaký jednochý úkol do střední školy, ale hodně složitou a hlavně nesmírně rozsáhlou aplikaci a poznámky o tom, že mám špatně navrženou databázi mi opravdu nepomůžou. Můžete mít na to jiný názor, ale já to nemůžu prostě pokaždé celý předělávat, když se objeví něco "nevhodného". To bych dělal ještě deset let než by to bylo hotový.. Tam je tolika věcí, že když se něco optimalizuje na jednu věc, tak to zase skřípe u tý druhý, takže hledám nějaký kompromis a pragmatické řešení konkrétního problému.
Tomášeek
Profil
quatzael:
snažím se tady už několikrát vysvětlit
V tom případě absolutně nechápu, proč se tu vlastně ptáš. Všichni ti tu píší, že to, co chceš, po tvém nejde, že na to jdeš prostě špatně. Ty si přesto neustále meleš tu svou. Proč se ptáš, když odpověď nechceš přijmout? Není to mrhání času, tvého i našeho?

To je přece nesmysl.
Proč?

Až tam budu mít 10 tis. smluv, tak tam budu mít přes milion záznamů.
nevím, jestli milion (každá smlouva má 100 atributů?). Každopádně, řádově miliony záznamů nejsou pro DB problém.

To nevím jak potom bude fungovat ten SELECT, když bude tahat 100 záznamů z milionu podle id_smlouvy
S indexy normálně. Je to běžná praxe.
Joker
Profil
quatzael:
Lze nějak použít přímo hodnotu ze sloupce jako součást názvu tabulky pro JOIN v tom samém dotazu?

Něco takového by přece nemohlo vůbec fungovat:
 SELECT * FROM contracts JOIN contracts_detail_{contracts.type} ON contracts.id = contracts_detail_{contracts.type}.contract_id 

To nejde vyhodnotit, je tam hned několik kruhových závislostí. Například na vyhodnocení toho JOINu musím nejdřív vědět jaké sloupce bude mít výsledek a to nevím bez vyhodnocení toho JOINu.
Krom toho by každý další záznam přidával nové sloupce, o kterých se nevědělo u předchozích záznamů (čili by to databáze musela vyhodnocovat opakovaně).

Pak jsou tu technická omezení, jako že každý další záznam přidává nové sloupce a maximální počet sloupců je 4096, takže by počet řádků musel být menší než nějaké maximum, které by bylo mezi 1 a 2048 a navíc by záviselo na hodnotách v řádku.


Mám pocit, že výsledek nejbližší tomu úmyslu by měl prostě JOIN všech těch tabulek:
SELECT * FROM contract c JOIN contract_detail_aaa daaa ON c.id=daaa.contract_id  JOIN contract_detail_bbb dbbb ON c.id=dbbb.contract_id JOIN (atd.)

Což vlastně ve výsledku bude:
to bych potom měl univerzální tabulku se stovkama sloupců, z nichž bych na každým řádku využil jenom pár

To nevím jak potom bude fungovat ten SELECT, když bude tahat 100 záznamů z milionu podle id_smlouvy..

Zrovna tohle docela v pohodě. Databáze jsou stavěné na to vybírat řádky. To naopak bude větší výkonový problém nějaký brutální JOIN.
TomášK
Profil
quatzael
poznámky o tom, že mám špatně navrženou databázi mi opravdu nepomůžou.

Co jiného ti máme říct, pokud to tak je? Máš špatný návrh a teď jsi narazil na problém, který v něm nejde dobře vyřešit. Typ dat, který popisuješ, je lepší ukládat jako strukturovanou hodnotu (XML, JSON, HStore) v nějaké NoSQL databázi nebo databázi, ktera s takovými hodnotami umí pracovat. Relační databáze na to není vhodná.

Řešení, které navrhuje Kajman (Entity–attribute–value model), je často považované za antipattern. Než to tak uděláš, je dobré si zjistit, co má za nevýhody.
quatzael
Profil
No pokud na to neexistuje ani žádný nekonvenční způsob, budu to muset vyřešit dvěma dotazy. To zase nebude asi tak hrozný jako překopávat celou databázi. Každopádně díky za reakce.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: