Autor Zpráva
freeTel
Profil *
Zdravím, v poslední debatě jsem asi pár lidí naštval, že jsem si dovolil mít vlastní názor a v posledním příspěvku se mnou ani opička nepromluvila. No i tak to zkusím a zeptám se na poslední věc: snažím se dosáhnout posloupnosti od nejvýdělečnějšího klienta. Představa o zápisu byla snadnější než jeho realizace (kopnu SUM(cena*pocet) a bude). Realizace byla jak napovídá nově založené vlákno úplně jiná. Dotaz je složitý nejen posloupností, ale i třema rozdílnýma ceníkama.

tabulka produkt má dvě ceny (cena, velcena). Pokud má uživatel v tabulce user cen_relace='Y' tak se bere z velcena. Protože jsem těch komplikací neměl málo, tak je ještě jedna tabulka pro individuální ceny (klient_cenik). Nevím, jestli se mnou tady začne zas někdo komunikovat, ale vzhledem k tomu, že se v tom plácám, tak to alespoň zkusím. Předem děkuji

$select = "SELECT ob.id_zbozi,pm.id,pm.nick,pr.nazev,pr.cena,pr.chs,kl.cenik,pm.nick,pm.cen_relace 
FROM
  user pm
LEFT JOIN objednavky ob
  ON ob.id_user=pm.id
LEFT JOIN produkty pr
  ON ob.id_zbozi=pr.id
LEFT JOIN klient_cenik kl 
  ON pr.id=kl.id_produktu 
  ORDER BY coalesce(kl.cenik,pr.cena) DESC";



Teď to mám takhle:
$select = "SELECT ob.id_zbozi,pm.id,pm.nick,pr.nazev,pr.cena,pr.chs,kl.cenik,pm.nick,pm.cen_relace,(pr.cena*ob.pocet) AS cena1,(kl.cenik*ob.pocet) AS cena2 
FROM
  user pm
LEFT JOIN objednavky ob
  ON ob.id_user=pm.id
LEFT JOIN produkty pr
  ON ob.id_zbozi=pr.id
LEFT JOIN klient_cenik kl 
  ON pr.id=kl.id_produktu
  ORDER BY coalesce(cena1,cena2) DESC";
a výsledek:

uzivatel1 - Testy - 2421 - 0
uzivatel1 - Test4 - 2000 - 10000
uzivatel2 - Test3 - 400 - 0
uzivatel1 - Test8 - 55 - 0
uzivatel2 - Test8 - 55 - 0
Řadí hezky až na druhou cenu. Tu ignoruje
Kajman
Profil
V posledním tématu jste psal, že jste to už vyřešil (pro další generace je dobré napsat jak, viz pravidla).

Funkce coalesce bere první nenullovou hodnotu, takže pokud klientská cena2 má přednost, má být na první místě. Ve výpisu máte však nuly a ne null hodnoty. To by pak nefungovalo.

Stejně mi to přijde celé nesmyslné. Pokud už máte nějakou objednávku, cena tam má být přece zafixovaná. Když pak změníte cenu produktu nebo uživatelský ceník, tak přece ztratíte informaci, za kolik si to vlastně loni koupil.
freeTel
Profil *
Kajman:
To jsem nevěděl, že se má psát řešení a nepovažuji se za programátora, který může dávat řešení. Jako jste tu řešili jednoho uživatele, tak jsem měl nutkání napsat svůj kód, který jsem si vytvořil před pár lety a je účinný, ale trošku prasárna. Tak jsem raději mlčel.

Když pak změníte cenu produktu nebo uživatelský ceník, tak přece ztratíte informaci, za kolik si to vlastně loni koupil.
Souhlasím. Ale ceník se nemění a v podstatě se každému dá jeho ceník fixně hned po registraci. Proto to cenu má.
Tomášeek
Profil
freeTel:
Ale ceník se nemění a v podstatě se každému dá jeho ceník fixně hned po registraci. Proto to cenu má.
Chceš mi říct, že pokud jsem se zaregistroval například v roce 2016 a cena vstupu/výroby od té doby vzrostla dvojnásobně, dodáváš mi zboží stále za cenu z roku 2016? Přestože to pro tebe je prodělečné? Jako fakt? :-)

Chodíš sem pro rady (což je v pořádku), ale když už ti někdo napíše správný postup, je fakt hloupé (a myslím, že zrovna tobě jsem to už jednou psal) to odpálkovat svými domněnkami, které mimochodem jsou i v tomto případě mimo. Ale dělej, jak myslíš.
freeTel
Profil *
Jinak jste měl pravdu s tím převrácením. Teď mi to řadí jak má. Jen pokud má mít uživatel cenu CHS a ne klasickou, tak ho rozděluji na cen_relace='Y'. Nevím jak to udělat aby v případě splnění podmínky byla dominantní CHS.

$select = "SELECT ob.id_zbozi,pm.id,pm.nick,pr.nazev,pr.cena,pr.chs,kl.cenik,pm.nick,pm.cen_relace,(pr.cena*ob.pocet) AS cena1,(kl.cenik*ob.pocet) AS cena2,(pr2.chs*ob.pocet) AS cena3 
FROM
  user pm
LEFT JOIN objednavky ob
  ON ob.id_user=pm.id
LEFT JOIN produkty pr
  ON ob.id_zbozi=pr.id
  
LEFT JOIN produkty pr2
  ON ob.id_zbozi=pr2.id AND cen_relace='Y'
  
LEFT JOIN klient_cenik kl 
  ON pr.id=kl.id_produktu
  ORDER BY coalesce(cena2,cena1,cena3) DESC";

uzivatel1 - Test4 - 10000000 - 10000 - 1000
uzivatel1 - Testy - 2421 - 0 - 2300
uzivatel2 - Test3 - 400 - 0 - 0
uzivatel2 - Test8 - 55 - 0 - 0
uzivatel1 - Test8 - 55 - 0 - 44


Tomášeek:
Dobrý postřeh, ale historie objednávky nemusí přeci sahat od vzniku stránek. Pokud si řeknu, že si dám cenu marže u každého produktu například 5,- kvůli inflaci, tak mi sice dá zavádějící výsledek ohledně cen, ale posloupnost zůstane stejná. To není, že by jsem ignoroval dobře mířenou radu. Jsem si toho vědom ještě před tím než jsem si sednul ke klávesnici.
Keeehi
Profil
freeTel:
Tak ony se ceny můžou měnit nezávisle na tvé vůli. Vláda uzákoní nové sazby DPH a šup, máš jiné ceny. Můžeš sice říct, že v takovém případě upravíš cenu bez DPH tak, aby cena s novou sazbou vycházela tak jako předtím. Ovšem tím bys udělal něco u čeho jsi tvrdil, že nastat nemůže - změnil jsi ceníkovou cenu.
Je samozřejmě možné mít uložené časy všech změn, které se postupně odehrávají a mohou vstoupit do ceny a když to bude potřeba, tak z toho zpětně rekonstruovat původní cenu. Ale je to příšerně složité a zbytečné. Je je mnohem jednodušší a taky se to tak dělá je právě to ukládání objednávky i s cenou v té době, nezávisle na cenících. Ono to jde tak daleko, že se ukládají i kopie jednotlivých položek, co v objednávce máš.
Ono to má jednu další výhodu, můžeš pak hýbat s cenami v té objednávce, aniž bys měnil ceníky. Například když chceš zákazníkovi dát na nějakou položku mimořádnou slevu, třeba z důvodu, že jsi mu ji posledně poslal pozdě.
Kajman
Profil
freeTel:
Zkuste vysvětlit finančnímu úřadu, že historii správných cen nemusíte mít. A hlavně si uvědomte, že vedlejším efektem ukládání cen budou jednoduché dotazy!

Pokud má mít nenullové chs přednost před obecnou cenu, tak pořadí parametrů ve funkci coalesce máte zase přehozené. Stále stejné chyby.
freeTel
Profil *
to opravím, ale jak udělat prosím to nahrazení?
freeTel
Profil *
Seřazený to už mám správně. Ted už jen sečíst ty ceny od uživatele
Kajman
Profil
freeTel:
Seřazený to už mám správně.

Ale tipuji, že to k ničemu není, když chcete řadit až součet. Možná hledáte něco jako

SELECT pm.id,
       pm.nick,
       Sum(Coalesce(kl.cenik, pr2.chs, pr.cena) * ob.pocet) AS soucet
FROM   user pm
       JOIN objednavky ob
         ON ob.id_user = pm.id
       JOIN produkty pr
         ON ob.id_zbozi = pr.id
       LEFT JOIN produkty pr2
              ON ob.id_zbozi = pr2.id
                 AND pm.cen_relace = 'Y'
       LEFT JOIN klient_cenik kl
              ON pr.id = kl.id_produktu
                 AND ob.id_user = kl.id_klienta
GROUP  BY pm.id,
          pm.nick
ORDER  BY soucet DESC
freeTel
Profil *
To je přesně ono. Takže jsem byl na dobré cestě. Bez Vás by jsem to nedal i když teď když na to koukám je to snadný, ale po bitvě je každý hrdina

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:

0