Odstranění duplicitních řádků z výsledku dotazu – MS SQL – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Odstranění duplicitních řádků z výsledku dotazu – MS SQL – Fórum – Programujte.comOdstranění duplicitních řádků z výsledku dotazu – MS SQL – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené.
MilanL+1
Grafoman
25. 1. 2017   #1
-
0
-

Dobrý den,

mám 4 tabulky číselníky (RadyProduktu, Produkty, Objemy) a tabulku definic produktů (ProduktyDef). V každém číselníku mám ID a název (Rada,Produkt,Objem) a další základní údaje, v tabulce ProduktyDef pak mám jednotlivé kombinace a další údaje jsou vytvořeny vazby na  číselníky (ID_Rady, ID_Prod, ID_Obj).

Dotaz SELECT na všechny kombinace funguje normálně, nedaří se mi vytvořit SQL pro filtry v programu,tak aby se např ve filtru Řad objevila každá řada jen 1 - když tam dám group by, tak to vyhazuje chyby.

SELECT ID_Rady, Rada, ID_Prod, Produkt, ID_Objemu, Objem_T
FROM HDL_ProduktyDef 
JOIN HDL_ProdRady AS r on ID_Rady=r.ID
JOIN HDL_Produkty AS p on ID_Prod=p.ID
JOIN HDL_Objemy AS o on ID_Objemu=o.ID
GROUP BY ID_Rady

.. chyb to dělá několik, když to je jako výše, tak to od 2. sloupečku vyhazuje chybu, že to není agregační údaj a když ty sloupečka dám třeba jako MAX(...), tak to zas hlásí že to nenalezlo daný Field. strávil jsem nad tím již několik hodin, hledání a zkoušení. Jediný funkční nápad co jsem měl bylo použití dočasné tabulky a seskupení nad ní.

Za jakoukoliv odpověď předem děkuji.

Milan L.

Nahlásit jako SPAM
IP: 91.139.9.–
MilanL+1
Grafoman
25. 1. 2017   #2
-
0
-

#1 MilanL
menší doplněk, v základu filtry z číselníků nejsou problém, problém nastává pokud chci vyfiltrovat jen řady, které obsahují daný produkt nebo produkty v dané řadě, když ke každé řadě/produktu může existovat více objemů nebo i definic.

Blbej snad nejsem např. obrácená funkčnost se mi povedla, kdy jsem potřeboval ke skupinám a produktům vybrat do přehledů pouze 1 nejnovější definici podle data vytvoření + celkový počet definic)

Nahlásit jako SPAM
IP: 91.139.9.–
25. 1. 2017   #3
-
0
-

Zkusil jsi poddotaz?

hu

Nahlásit jako SPAM
IP: 195.178.67.–
MilanL+1
Grafoman
25. 1. 2017   #4
-
0
-

#3 hlucheucho
Zkoušel jsem už všechno možné trápím se s tím 3. den, vždycky když mě při další práci něco napadne, tak to vyzkouším, ale nedaří a nedaří se, Bez GROUP BY a závorek je to v pohodě, jak tam něco z toho přidám jde to do háje.

Nahlásit jako SPAM
IP: 91.139.9.–
25. 1. 2017   #5
-
0
-

Zkus podrobněji popsat tabulky - ke každé vyspat sloupce a  jak má vypadat výsledek.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
MilanL+1
Grafoman
25. 1. 2017   #6
-
0
-

Ty tabulky jsem popisoval ve 3 základních tabulkách (čiselníkách) jsou podstatné 2 základní sloupečky, 

ID - celé číslo (autoinc),

Rada / Produkt / Objem - název podle tabulky string omezené délky od 5 do 40 znaků

další sloupce jsou pro potřebu daného dotazu zbytečné (jsou tam zkrácené názvy, index poznámky a u produktů nějaké detaily)

Ve 4 tabulce Produkty definice se to spojuje

ID (autoinc), ID_Prod, ID_Rady, ID_Objemu - z číselníků + další údaje pro dotaz nepotřebné (hustota, koncentrace kapalin, datum, platnost, apod)

Program je v DELPHI, DB je MS SQL přistupuji přes ADO, a potřebuji do formulářových DBLOOKUPcombobox dostat seznamy pro ŘADY, PRODUKTY a OBJEMY, když je to prázdné mohu zdroj nastavit přímo na tabulky, ale v okamžiku, kdy do jednoho z filtrů něco zadám je třeba, aby se ostatní zaktualizovali a obsahovali jen to co je provázané přes tu 4. definiční tabulku a aby tam každá ta vybraná řádka byla jen jednou (např. když produkt bude třeba ve 3. řadách a v každé řadě bude mít 2 objemy, tak základní dotaz udělá 6. řádek (3řady*2objemy), potřebuji, aby se ve filtru ŘAD objevili jen 3. různé řádky a ve filtru OBJEMů jen 2, samozřejmě na každý filtr bude třeba extra dotaz. Vidím to nejspíš na tu pomocnou dočasnou tabulku, tam už mi to fungovalo.

Nahlásit jako SPAM
IP: 91.139.9.–
peter
~ Anonymní uživatel
4016 příspěvků
25. 1. 2017   #7
-
0
-

Viz hlucheucho. Seznam tabulek, struktura, vysledek vzor.

Priklad
lide: id_lide, jmeno, prijmeni, id_bydliste
bydliste: id_bydliste, mesto

 Vyber vsechna Brna z tabulky bydlist a prilep k nim cloveka

SELECT
  a.mesto, 
  b.jmeno, 
  b.prijmeni
FROM
  bydliste a
    LEFT JOIN lide b ON b.id_bydliste=a.id_bydliste
WHERE
  a.mesto="Brno"

Vyber vsechny lidi, prilep k nim radky z bydliste a porovnej, kteri jsou z Brna

SELECT
  b.mesto, 
  a.jmeno, 
  a.prijmeni
FROM
  lide a
    LEFT JOIN bydliste b ON b.id_bydliste=a.id_bydliste
WHERE
  b.mesto="Brno"

A kdyz mas 3 tabulky, tak se vyplati udelat pro kazde porovnani vyber zvlast a zgrupovat to. Napr
(
- lide bydl = Brno: id_lide
- lide jmeno = Jan: id_lide
GROUP BY id_lide -- vyrobi seznam id_lide podle podminek,
) LEFT JOIN ostatni tabulky na vysledek.
Podminku muzes mit treba OR (Jan nebo z Brna) nebo AND (Janove z Brna); count>0, count=2
Bylo by zbytecne tam vzdy pripojovat vsechny udaje, kdyz te nejdriv stejne zajimaji idecka.

U klasickeho JOIN bacha, tam musis vedet, proc a jak ho pouzivas. Tudle tady nejaci studenti delali program na vyber publikaci podle autoru a kdyz zadali 6 autoru a asi 1000 publikaci, tak to zahltilo procesor na 10 dni :) Nekterou ved. publikaci pise cely tym, treba 3-4 autori. A tazatele zajimalo, kolik publikaci vydalo konkretnich 6 osob. Kdyz si dal kazdeho autora zvlast, tak dotaz udelal blik a hotovo. Takze jsem dotaz slozil ze 6 dotazu a zgupoval to. Oni to meli udelane JOINY a tam se to umocnovalo a vytvarela jedna giganticka tabulka v pameti
((((((1000) na 1000) na 1000) na 1000) na 1000) na 1000)
No, i takove veselosti te muzou potkat :)

Nahlásit jako SPAM
IP: 2001:718:2601:26c:140c:57...–
peter
~ Anonymní uživatel
4016 příspěvků
25. 1. 2017   #8
-
0
-

Aha, takze mozna chces jen jednoduchy dotaz. Nejsem si ale jisty, jestli chapu, co je ve ktere tabulce, co vlastne vybiras. Tu, ze ktere vybiras, musi byt ta prvni. Na tu nabalujes ostatni. Treba, chces seznam knih, ktere napsal autor. Tak prvni tabulka je propojeni id_autor, id_kniha. Na tu nabalis tabulku s nazvem knih a jmena autoru.

SELECT
  a.ID_Rady,
  b.Rada,
  c.Produkt,
  d.Objem_T
FROM
  (
  SELECT ID_Rady, Rada, ID_Prod, Produkt, ID_Objemu, Objem_T
FROM
  HDL_ProduktyDef a
    LEFT JOIN HDL_ProdRady AS b on b.ID=a.ID_Rady
    LEFT JOIN HDL_Produkty AS c on c.ID=a.ID_Prod
    LEFT JOIN HDL_Objemy AS d on o.ID=a.ID_Objemu
WHERE
  a.ID_Rady=5 AND
  a.ID_Prod=5 AND
  a.ID_Objemu=6
Nahlásit jako SPAM
IP: 2001:718:2601:26c:140c:57...–
peter
~ Anonymní uživatel
4016 příspěvků
25. 1. 2017   #9
-
0
-

 jo, to tam nema byt, to jsou zapomenute pomocne radky z tveho dotazu

  (
  SELECT ID_Rady, Rada, ID_Prod, Produkt, ID_Objemu, Objem_T
FROM
Nahlásit jako SPAM
IP: 2001:718:2601:26c:140c:57...–
peter
~ Anonymní uživatel
4016 příspěvků
25. 1. 2017   #10
-
0
-

   

SELECT
  a.ID_Rady,
  b.Rada,
  c.Produkt,
  d.Objem_T
FROM
  HDL_ProduktyDef a
    LEFT JOIN HDL_ProdRady AS b on b.ID=a.ID_Rady
    LEFT JOIN HDL_Produkty AS c on c.ID=a.ID_Prod
    LEFT JOIN HDL_Objemy AS d on d.ID=a.ID_Objemu -- a tady melo byt d.ID
WHERE
  a.ID_Rady=5 AND
  a.ID_Prod=5 AND
  a.ID_Objemu=6
Nahlásit jako SPAM
IP: 2001:718:2601:26c:140c:57...–
MilanL+1
Grafoman
25. 1. 2017   #11
-
0
-

#10 peter
to je základní dotaz to mi fungovalo, problém mám s duplicitami na výstupu, když zadám třeba jen 1 z podmínek např. produkt=X, který je v 10 řadách a v některé má třeba 2-3 různé objemy, tak my z tohohle dotazu vyleze 10-30 řádek s tím, že se některé opakují - TOTO potřebuji odstranit.

Už mi to částečně funguje

SELECT
     s.Rada
FROM (
     SELECT 
          r.Rada Rada
     FROM HDL_ProduktyDef as d
          LEFT JOIN HDL_ProdRady AS r ON r.ID=d.ID_Rady
          LEFT JOIN HDL_Produkty AS p ON p.ID=d.ID_Prod
          LEFT JOIN HDL_Objemy AS o ON o.ID=d.ID_Objemu
     ) s
GROUP BY s.Rada

ovšem filtrování (podmínky) z vnějšku asi nepůjde co?

Delphi ADODataSet - kod v CommandTextu a podmínky se dávají do Filter, parametry z vnějšku mi taky nějak nešli, navíc fungujou jen, když se tam něco dá, asi bych musel vytvořit pro každej číselník vytvořit defaultní záznamy pro ID_Prod/ID_Objemu=0 + všechny Řady, a stejně tak pro objemy a produkty.

Nejspíš si ten dotaz hodím do string konstanty s označením místa kam patří podmínky a co se filtruje, a budu nahrazovat označení tím co budu potřebovat a následně vložím do CommandTextu.

Díky za pomoc a snahu. posílám vám karmu.

Nahlásit jako SPAM
IP: 91.139.9.–
gna
~ Anonymní uživatel
1891 příspěvků
25. 1. 2017   #12
-
0
-

Už jsi příšel na to, že tabulka má ve všech sloupích stejný počet řádků, takže každé combo musí mít vlastní zdroj.

Jen změníš vybrané sloupce a odstraníš duplicity, co víc chceš vymýšlet?

SELECT DISTINCT Rada
<zbytek stejný jako pro DataSource>

A ano, budeš tak nejméně 4krát dělat praktický stejný dotaz, což je naprostá krávovina a chtělo by to řešit úplně jinak.

Nahlásit jako SPAM
IP: 213.211.51.–
26. 1. 2017   #13
-
0
-

Když jsem potřeboval aby si uživatel volil další podmínky, vytvářel jsem řetězec s dotazem dynamicky. Měl jsem základní dotaz a když uživatel zaškrtl vyhledat podle názvu, přidal jsem do podmínky "AND nazev = ?pnazev" a naplnil parametr ?pnazev požadovanou hodnotou. Takto připravený dotaz jsem pak nechal vykonat. Co si ještě pamatuju z doby, kdy jsem používal C++ Builder, ADO komponenty uměly v dotazech používat parametry. Embarcadero teď masivně doporučuje a podporuje FireDAC. Ten obsahoval chybu která nepravidelně způsobovala vyjímku, tato chyba byla odstraněna až u verze XE6. U některých edicí Delphi může být omezen jen na lokální připojení k databázi.

Vždy jsem se maximálně vyhýbal třídění, řazení ... na straně klienta. Na straně databáze jsou na to optimalizované algoritmy a většinou je tam i dostatečně výkonný stroj.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
MilanL+1
Grafoman
26. 1. 2017   #14
-
0
-

#13 hlucheucho
Já v základním SQL ještě nejsem příliš zkušený neznám ještě všechny řídící slova a jejich použití, ten distinct mi v podstatě všechno vyřešil navíc vzhledem k tomu, že pro každý combobox potřebuji jiný seznam tak jsem to zjednodušil vždy jen ta detailní tabulka + 1 číselník ze kterého tahám název.

Dříve jsem používal na db aplikace MS ACCESS (obchodní/skladová evidence, provoz SDP a agregátů, Peněžní deník), ale tato aplikace zpracovává ovládá měřící přístroje a vyčítá z nich data a to mi v Acc udělat nešlo,

Vzhledem k tomu, že v té detailní tabulce se plánují zatím jen stovky max pár tisíc záznamů a dataset má jen 3sloupečky (text + 2 indexy na filtr), tak neřeším zda filtrovat již na straně serveru nebo klienta - navíc program i SQLserver pojedou na stejném PC (zkusím si to stopnout kolik času zabere filtr na datasetu a kolik změna dotazu). V současnosti mi jde hlavně o funkcionalitu a zprovoznění, až to pojede tak plánuji optimalizace. 

Nahlásit jako SPAM
IP: 91.139.9.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 5 hostů

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý