Autor Zpráva
tomas2245
Profil
zdravím, nechcem zakladať novú tému, tak využijem túto nato:
Moderátor juriad: Vyčleněno z Jak zkrátit dotaz v MYSQL


chcel by som sa spýtať či sa dá nejak rozumnejšie napísať takýto dotaz, neviem či to časom nebude nejak extra pomalé, keď v každej tabuľke bude cca 400 riadkov s informáciami...

dotaz vypadá takto:

$dotaz = mysqli_query($pripoj,"SELECT * FROM tabulka1 WHERE skupina = '1' 
    UNION SELECT * FROM tabulka2 WHERE skupina = '1'
    UNION SELECT * FROM tabulka3 WHERE skupina = '1'
    UNION SELECT * FROM tabulka4 WHERE skupina = '1' ORDER BY ID DESC");
juriad
Profil
tomas2245:
Hlavně bys neměl mít potřebu číslovat tabulky, máš nejspíš špatně navrženou databázi. Záznamy stejné povahy patří do stejné tabulky. Pokud se nějak liší, tak ty rozdíly patří do dalších tabulek, které se připojují k té hlavní. UNION je potřeba jen zřídka.

Další věc. Jelikož porovnáváš skupina = '1', chápu správně, že sloupec skupina je textový a nikoli číselný, je to správně?

400 záznamů je nic, databáze zvládají tisícinásobně více. Pokud ovšem máš správně navrženou strukturu.
tomas2245
Profil
juriad:
tabuľky číslujem podľa rokov: objednavky_2017, objednavky_2018...
štruktúra týchto tabuliek je rovnaká, mal by som to v jednej tabuľke napr. len objednavky ale prerobil som to podľa rokov preto, aby som zákazníkov čísloval pomocou AUTO_INCREMENT a začínalo to v každom roku od 1... (potrebujem to pre číslovanie zákazníka)

áno stĺpec skupina je textový (varchar)

a ako by prosím ťa vyzeral ten môj dotaz na JOIN? + je to moc potrebné aby som tam mal JOIN miesto UNION, keď štruktúra tabuliek je rovnaká?
juriad
Profil
tomas2245:
To děláš úplně špatně, všechny objednávky patří do jedné tabulky. Máš nějaký dobrý důvod číslovat od jedničky? Navíc, ID by nemělo mít žádný zvláštní význam; pro jiný způsob číslování můžeš přidat další sloupec, který slouží jen k tomuto.

Pokud nehodláš používat jedinou tabulku, UNIONu se nevyhneš. JOIN jsem nadhodil proto, že z [#1] nebylo poznat, k čemu to potřebuješ (kdybys třeba měl tabulky prijate_objednavky, zaplacene_objednavky a vyrizene_objednavky (lišící se pár sloupci) a data mezi nimi přesouval, tak by deduplikace a JOIN mohl být řešením)
tomas2245
Profil
juriad:
áno, pre lepšiu orientáciu v objednávkach v danom roku je veľmi dobré riešenie to mať od 1

Navíc, ID by nemělo mít žádný zvláštní význam: a to prečo? veď len vypisujem hodnotu: Č. zákazníka: '.$dotaz['id'].'
pcmanik
Profil
tomas2245:
Pre akú lepšiu orientáciu? V aplikácii hádam máš filter na roky, tak aký je teda dôvod deliť dáta do tabuliek? Okrem problémov to nič neprináša.

Číslo zákaznika má byť unikátne, ty takto budeš mať každý rok zákazníka s id 1...
Keeehi
Profil
tomas2245:
a to prečo? veď len vypisujem hodnotu
Tím je myšleno, že id v6854ser1safjhb je stejně dobré jako id 241. ID by nejlépe nemělo nic vyjadřovat, žádné pořadí, žádný čas přidání záznamu, prostě nic. Jeho jediným úkolem je být unikátní. Číslovat si zákazníky můžeš v jiném sloupci. Jak to tak vidím, tak by tomu slušela jedna tabulka, kde bys měl sloupec ID a vůbec by ses o něj nestaral (nepřiřazoval bys mu žádnou vypovídající hodnotu), dále sloupec rok, sloupec s pořadím objednávky v daném roce a pak další sloupce co už máš.
tomas2245
Profil
Keeehi:
a ako by som to spravil tak, aby pre každý rok teraz je: 2017 tak by to išlo od 1 a v tej istej tabuľke by bol potom rok 2018 a v tom istom stĺpci ,,poradie objednávky v danom roku" by to išlo zase od 1? veď to sa ani nedá spraviť či?


pcmanik:
áno, ale mňa vôbec nezaujíma objednávka v administrácií, ja ju potrebujem vytlačiť na A4.
Proste nechcem mať číslovanie zákazníka v tisícoch za tie roky sa to nazbiera...
v administrácií to teraz delím ./administracia/objednavka.php?id=1&rok=2017 na základe týchto dvoch $_GET sa teda načíta dotaz z tabuľky objednavky_2017 ak tam je "&rok=2018" tak sa načíta tabuľka objednavky_2018..

$idecko = mysqli_real_escape_string($pripoj,$_GET['id']);

if($_GET['rok'] == "2017" && !empty($_GET['id'])){
$dotaz = mysqli_query($pripoj,"SELECT * FROM objednavky_2017 WHERE id='$idecko'");
$dotaz = mysqli_fetch_array($dotaz);
}
pcmanik
Profil
tomas2245:
Lepšie je filtrovať dáta podľa dátumu, resp. roku. Ako vyberať ich z iných tabuliek. Čo ak napríklad zabudneš vytvoriť novú tabuľku pre rok 2018? Zákazníci nebudú môcť robiť objednávky? Čo ak budeš chceť pridať nový stĺpec? Budeš ho pridávať do viacerých tabuliek namiesto jednej? A ďalších príkladov prečo je to zlé sa dá najsť oveľa viac.

Zákaznikom je ich číslo / číslo objednávky ukradnuté a tebe by malo byť tiež a nie kvôli tomu "ohýbať" databázu do zlej podoby.

Proste nechcem mať číslovanie zákazníka v tisícoch za tie roky sa to nazbiera...
Ty ale nemáš číslovať zákazníkov, ale objednávky. Alebo snaď si jeden zákazník môže vytvoriť len jednu objednávku a viac nie?
tomas2245
Profil
pcmanik:
máš pravdu číslovať objednávky.. a samozrejme chápem, je to zdĺhavé potom upravovať všetky kódy pre ďalší rok, ale som v tomto začiatočník, a prišiel som na takéto riešenie, samozrejme dalo by sa to spraviť oveľa lepšie...porozmýšľam nad tým, a asi vážne to prerobím na 1 tabuľku a vykašlem sa na to číslovanie :D keď mám pravdu povedať, tak hlavný dôvod prečo som sa to rozhodol deliť do viacerých tabuliek bol ten, že som sa bál že ak to bude moc preplnené že to bude pomalšie brať odtiaľ údaje..
CZechBoY
Profil
tomas2245:
Nejhorší optimalizace je předčasná optimalizace.
Keeehi
Profil
tomas2245:
2017 tak by to išlo od 1 a v tej istej tabuľke by bol potom rok 2018 a v tom istom stĺpci ,,poradie objednávky v danom roku" by to išlo zase od 1? veď to sa ani nedá spraviť či?
Nevím kde vidíš problém. Ta tabulka může vypadat takto:
id   | rok  | poradi zakaznika | nejaka dalsi data
--------------------------------------------------
5421 | 2015 | 1                | aaaaaaaa
5422 | 2015 | 2                | bbbbbbbb
5423 | 2016 | 1                | cccccccc
6841 | 2016 | 2                | dddddddd
6842 | 2016 | 3                | eeeeeeee
1954 | 2016 | 4                | ffffffff
Schválně si všimni IDček. Mohou v nich být díry, nemusí růst. A přesto to vůbec ničemu nevadí. Všechny podstatné věci, co tě zajímají, jsou v dalších sloupcích. IDčko je jen technický prostředek a to že se k tomu využívá často nějaká rostoucí číselná řada je něco, čeho by sis vůbec neměl všímat a ani na to spoléhat. Rostoucí číselná řada se používá jen proto, že je to velmi jednoduché řešení jak zajistit unikátnost hodnoty.
tomas2245
Profil
Keeehi:
ja rozumiem tej štruktúre, skôr nechápem ako docieliť to, že to poradie zákazníka pôjde furt od 1 na základe roku
či myslel si to tak, že ja budem tam to poradie zákazníka cez administráciu zapisovať manuálne?
Keeehi
Profil
tomas2245:
Automaticky to databáze dělat nebude, ale PHP script to zvládne. Prostě si před vytvořením nového záznamu načte největší číslo pro daný rok, zvětší ho o jedna a to vloží do toho nového záznamu.
tomas2245
Profil
Keeehi:

to šlo takto jednoducho spraviť :D a ja som kvôli tomu prekopal celý systém popridával tabuľky podľa rokov a neviem čo všetko :D ešte raz ďakujem :) :)
CZechBoY
Profil
To asi nebude moc atomicky... Mozna s pouzitim lock table to bude ok.
pcmanik
Profil
Riešením sú transakcie + plus správne zamykanie tabuliek. Ale v tomto prípade som si takmer istý že to určite problém nespôsobí, nakoľko problémov v samotnej aplikácii bude ďaleko viac a určite závažnejśích :)
Keeehi
Profil
CZechBoY:
Neatomicity jsem si vědom. Určitě by šla řešit unikátním indexem přes sloupce rok a pořadí případně tím zamykáním. Jak to tak ale vypadá, tomas2245 bude nejspíše jediným uživatelem systému a tak to nejspíše problém nebude.
tomas2245
Profil
Keeehi, CZechBoY, pcmanik:
nerozumiem vôbec, o akej automicity sa to bavíte, v čom by mohol byť konkrétne problém?
pcmanik
Profil
tomas2245:
Ak by dvaja užívatelia v rovnakom okamihu vytvorili objednávku, tak sa môže stať že by si im vygeneroval rovnaké poradie zákazníka. Ale ak tie objednávky vytváraš ty, tak to nieje problém.
tomas2245
Profil
pcmanik:
aha, no a som prišiel na ďalší problém že ak vymažem objednávku z nejakého dôvodu, tak keď príde nová tak sa zduplikuje s posledným číslom objednávky.. a to sa myslím že vyriešiť už nedá, aby sa vždy zachovalo poradie

pretože ten kód mám takto:

$cislo = mysqli_query($pripoj,"SELECT id FROM objednavky WHERE YEAR(cas) = YEAR(CURDATE())");
$cisloobjednavky = mysqli_num_rows($cislo);
$cisloobjednavky+=1;
pcmanik
Profil
tomas2245:
Sám teda vidíš ze tvoje riešenie má viac nedostatkov ako úžitku.

Ale dá sa aj toto vyriešiť vyberaj z db MAX(id) a k tomu pripočítaj 1 a nie všetky id a spočítavať ich...
Keeehi
Profil
tomas2245:
$result = mysqli_query($pripoj,"SELECT max(`poradi objednavky`) FROM objednavky WHERE YEAR(cas) = YEAR(CURDATE())");
if (mysqli_num_rows($result)) {
    $row = mysqli_fetch_row($result);
    $cisloobjednavky = $row[0] + 1;
} else {
    $cisloobjednavky = 1;
}

Další věcí je, že objednávky není třeba mazat. Potřebuješ-li nějak rozlišovat, zda je aktivní či ne, tak si přidej sloupec stav, ale záznamy nemaž.
tomas2245
Profil
pcmanik, Keeehi:
ďakujem vám, veľmi ste mi pomohli :)

Keeehi:
okej tak záznamy mazať nebudem, a pridám tam stĺpec stav. :)
inak ten tvoj kód funguje, ale len ak je objednávok menej ako 10 potom už to generuje len 10, 10, 10
Keeehi
Profil
tomas2245:
Nemáš ten sloupec (poradi objednavky) nastaven jako textový? To je jediné, co mě napadá.
tomas2245
Profil
Keeehi:
mal som :-D , a už som to zmenil a ide to.. diky

Vaše odpověď

Mohlo by se hodit

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

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