🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.bazy-danych
11 messages
11 total messages Started by Roman Tyczka Wed, 13 Jul 2016 13:22
Zapytanie eliminujące bez podzapytań (master-detail-detail)
#195028
Author: Roman Tyczka
Date: Wed, 13 Jul 2016 13:22
47 lines
1976 bytes
Hi,

Mam 3 tabelki w relacji master-detail-detail:
RODZICE
ID|  IMIE
 1| MARIA
 2| JAN
 3| KATARZYNA
 4| PIOTR

DZIECI
ID|   IMIE| ID RODZICA
 1| JULKA | 1
 2| ZOSIA | 1
 3| HENIU | 2
 4| ZUZIA | 3
 5| VIOLA | 4

ZABAWKI
ID| NAZWA | ID DZIECKA
 1| LALKA | 1
 2| AUTKO | 2
 3| KLOCKI| 3
 4| PIŁKA | 4
 5|   GRA | 5
 6| PISTOL| 3
 7| LALKA | 4

Każde dziecko może mieć kilka zabawek, każdy rodzic kilkoro dzieci.
Jak za pomocą jednego selecta wydobyć tylko tych rodziców, których dzieci
nie mają określonych zabawek, np. lalki?

Z powyższych danych zapytanie ma zwrócić tylko JANA i PIOTRA,  bo dziecko
MARII oraz dziecko KATARZYNY mają lalkę.

SELECT R.ID, R.IMIE FROM RODZICE R
JOIN DZIECI D ON D.IDRODZICA = R.ID
JOIN ZABAWKI Z ON Z.IDDZIECKA = D.ID
WHERE  ???

ps. umiem to zrobić z podzapytaniem w sekcji where, ale chciałbym się
dowiedzieć czy można prościej


-- 
pozdrawiam
Roman Tyczka
Re: Zapytanie eliminujące bez podzapytań (master-detail-detail)
#195029
Author: Adam M
Date: Wed, 13 Jul 2016 18:12
64 lines
2746 bytes
mozna to zrobic na dwa sposoby:
eliminacja w where lub w join

-> w where
SELECT R.ID, R.IMIE FROM RODZICE R 
JOIN DZIECI D ON D.IDRODZICA = R.ID 
JOIN ZABAWKI Z ON Z.IDDZIECKA = D.ID 
WHERE z.id not in (1)

- w join
SELECT R.ID, R.IMIE FROM RODZICE R 
JOIN DZIECI D ON D.IDRODZICA = R.ID 
JOIN ZABAWKI Z ON Z.IDDZIECKA = D.ID and z.id not in (1)



On Wednesday, July 13, 2016 at 9:22:43 AM UTC-4, Roman Tyczka wrote:
> Hi,
> 
> Mam 3 tabelki w relacji master-detail-detail:
> RODZICE
> ID|  IMIE
>  1| MARIA
>  2| JAN
>  3| KATARZYNA
>  4| PIOTR
> 
> DZIECI
> ID|   IMIE| ID RODZICA
>  1| JULKA | 1
>  2| ZOSIA | 1
>  3| HENIU | 2
>  4| ZUZIA | 3
>  5| VIOLA | 4
> 
> ZABAWKI
> ID| NAZWA | ID DZIECKA
>  1| LALKA | 1
>  2| AUTKO | 2
>  3| KLOCKI| 3
>  4| PIŁKA | 4
>  5|   GRA | 5
>  6| PISTOL| 3
>  7| LALKA | 4
> 
> Każde dziecko może mieć kilka zabawek, każdy rodzic kilkoro dzieci.
> Jak za pomocą jednego selecta wydobyć tylko tych rodziców, których dzieci
> nie mają określonych zabawek, np. lalki?
> 
> Z powyższych danych zapytanie ma zwrócić tylko JANA i PIOTRA,  bo dziecko
> MARII oraz dziecko KATARZYNY mają lalkę.
> 
> SELECT R.ID, R.IMIE FROM RODZICE R
> JOIN DZIECI D ON D.IDRODZICA = R.ID
> JOIN ZABAWKI Z ON Z.IDDZIECKA = D.ID
> WHERE  ???
> 
> ps. umiem to zrobić z podzapytaniem w sekcji where, ale chciałbym się
> dowiedzieć czy można prościej
> 
> 
> -- 
> pozdrawiam
> Roman Tyczka
Re: Zapytanie eliminujące bez podzapytań (master-detail-detail)
#195031
Author: Roman Tyczka
Date: Wed, 13 Jul 2016 20:43
70 lines
2894 bytes
To nie zadziała, warunkiem było, żeby odrzucało rodziców, których choćby
jedno dziecko ma lalkę. Zauważ, że MARIA ma dwie córki, JULIE i ZOSIE, i
mimo, że tylko jedna z nich ma lalkę to MARIA już powinna być pominięta w
wyniku, a nie będzie, bo załapie się przez drugą córkę.
I to jest właśnie problem.
Inny pomysł?

-- 
pozdrawiam
Roman Tyczka


On Wed, 13 Jul 2016 11:12:36 -0700 (PDT), Adam M wrote:
> mozna to zrobic na dwa sposoby:
> eliminacja w where lub w join
> 
> -> w where
> SELECT R.ID, R.IMIE FROM RODZICE R 
> JOIN DZIECI D ON D.IDRODZICA = R.ID 
> JOIN ZABAWKI Z ON Z.IDDZIECKA = D.ID 
> WHERE z.id not in (1)
> 
>> Mam 3 tabelki w relacji master-detail-detail:
>> RODZICE
>> ID|  IMIE
>>  1| MARIA
>>  2| JAN
>>  3| KATARZYNA
>>  4| PIOTR
>> 
>> DZIECI
>> ID|   IMIE| ID RODZICA
>>  1| JULKA | 1
>>  2| ZOSIA | 1
>>  3| HENIU | 2
>>  4| ZUZIA | 3
>>  5| VIOLA | 4
>> 
>> ZABAWKI
>> ID| NAZWA | ID DZIECKA
>>  1| LALKA | 1
>>  2| AUTKO | 2
>>  3| KLOCKI| 3
>>  4| PIŁKA | 4
>>  5|   GRA | 5
>>  6| PISTOL| 3
>>  7| LALKA | 4
>> 
>> Każde dziecko może mieć kilka zabawek, każdy rodzic kilkoro dzieci.
>> Jak za pomocą jednego selecta wydobyć tylko tych rodziców, których
dzieci
>> nie mają określonych zabawek, np. lalki?
>> 
>> Z powyższych danych zapytanie ma zwrócić tylko JANA i PIOTRA,  bo
dziecko
>> MARII oraz dziecko KATARZYNY mają lalkę.
>> 
>> SELECT R.ID, R.IMIE FROM RODZICE R
>> JOIN DZIECI D ON D.IDRODZICA = R.ID
>> JOIN ZABAWKI Z ON Z.IDDZIECKA = D.ID
>> WHERE  ???
>> 
>> ps. umiem to zrobić z podzapytaniem w sekcji where, ale chciałbym się
>> dowiedzieć czy można prościej
>> 
>> 
>> -- 
>> pozdrawiam
>> Roman Tyczka
Re: Zapytanie eliminujące bez podzapytań (master-detail-detail)
#195034
Author: wloochacz
Date: Thu, 14 Jul 2016 07:05
21 lines
1957 bytes
W dniu 2016-07-13 o 22:43, Roman Tyczka pisze:
>
> To nie zadziała, warunkiem było, żeby odrzucało rodziców, których choćby
> jedno dziecko ma lalkę. Zauważ, że MARIA ma dwie córki, JULIE i ZOSIE, i
> mimo, że tylko jedna z nich ma lalkę to MARIA już powinna być pominięta w
> wyniku, a nie będzie, bo załapie się przez drugą córkę.
> I to jest właśnie problem.
> Inny pomysł?
Odpis POD a nie NAD postem, dobrze?

Skoro umiesz podzapytaniem, to go użyj.
O ile wiem, w takim przypadku nie da się napisać statycznego warunku 
WHERE. Bo nie masz tam statycznych danych - musisz sprawdzić co, kto ma 
przypisane.
Czyli najpierw złączenia, a potem z wyniku po złączeniach drugim 
zapytaniem odrzucasz wiersze, które nie spełniają wymagań.

A jeśli umiesz użyć CTE, to będzie łatwiej, szybciej i prościej.

-- 
wloochacz
Re: Zapytanie eliminujące bez podzapytań (master-detail-detail)
#195036
Author: Roman Tyczka
Date: Thu, 14 Jul 2016 12:36
24 lines
1913 bytes
On Thu, 14 Jul 2016 09:05:25 +0200, wloochacz wrote:

>> Inny pomysł?
> Odpis POD a nie NAD postem, dobrze?

OK
 
> Skoro umiesz podzapytaniem, to go użyj.
> O ile wiem, w takim przypadku nie da się napisać statycznego warunku 
> WHERE. Bo nie masz tam statycznych danych - musisz sprawdzić co, kto ma 
> przypisane.
> Czyli najpierw złączenia, a potem z wyniku po złączeniach drugim 
> zapytaniem odrzucasz wiersze, które nie spełniają wymagań.

No to słabo... w sumie to chyba dość powszechny problem i dziwi mnie, że 
SQL tego nie ułatwia jakoś.

> A jeśli umiesz użyć CTE, to będzie łatwiej, szybciej i prościej.

CTE nie zmieni działania tylko go opakuje w ładniejszą formę.

-- 
pozdrawiam
Roman Tyczka
Re: Zapytanie eliminujące bez podzapytań (master-detail-detail)
#195040
Author: tomek
Date: Thu, 14 Jul 2016 15:28
86 lines
3100 bytes
----- Original Message ----- 
From: "Roman Tyczka" <noemail@because.no>
Newsgroups: pl.comp.bazy-danych
Sent: Wednesday, July 13, 2016 3:22 PM
Subject: Zapytanie eliminujące bez podzapytań (master-detail-detail)


> Hi,
>
> Mam 3 tabelki w relacji master-detail-detail:
> RODZICE
> ID|  IMIE
> 1| MARIA
> 2| JAN
> 3| KATARZYNA
> 4| PIOTR
>
> DZIECI
> ID|   IMIE| ID RODZICA
> 1| JULKA | 1
> 2| ZOSIA | 1
> 3| HENIU | 2
> 4| ZUZIA | 3
> 5| VIOLA | 4
>
> ZABAWKI
> ID| NAZWA | ID DZIECKA
> 1| LALKA | 1
> 2| AUTKO | 2
> 3| KLOCKI| 3
> 4| PIŁKA | 4
> 5|   GRA | 5
> 6| PISTOL| 3
> 7| LALKA | 4
>
> Każde dziecko może mieć kilka zabawek, każdy rodzic kilkoro dzieci.
> Jak za pomocą jednego selecta wydobyć tylko tych rodziców, których dzieci
> nie mają określonych zabawek, np. lalki?
>
> Z powyższych danych zapytanie ma zwrócić tylko JANA i PIOTRA,  bo dziecko
> MARII oraz dziecko KATARZYNY mają lalkę.
>
> SELECT R.ID, R.IMIE FROM RODZICE R
> JOIN DZIECI D ON D.IDRODZICA = R.ID
> JOIN ZABAWKI Z ON Z.IDDZIECKA = D.ID
> WHERE  ???
>
> ps. umiem to zrobić z podzapytaniem w sekcji where, ale chciałbym się
> dowiedzieć czy można prościej



SELECT R.ID, R.IMIE, D.IMIE, Z.NAZWA
FROMRODZICE R
INNER JOIN DZIECI D
LEFT JOIN ZABAWKI Z ON Z.IDDZIECKA = D.ID AND Z.NAZWA = 'LALKA'
WHERE 1
AND D.IDRODZICA = R.ID

Otrzymasz listę par rodzic-dziecko gdzie w kolumnie Z.NAZWA czasem będzie 
LALKA a czasem NULL

-----------------------------------------------------------------------------------------------
Teraz można kombinować dalej (MYSQL)
i pogrupować po rodzicu:
(coś + NULL) => NULL

SELECT R.ID, R.IMIE, D.IMIE,
  CONCAT(Z.NAZWA) AS nazwaZabawki

FROM RODZICE R
INNER JOIN DZIECI D
LEFT JOIN ZABAWKI Z ON Z.IDDZIECKA = D.ID AND Z.NAZWA = 'LALKA'
WHERE 1
AND D.IDRODZICA = R.ID

GROUP BY R.ID
HAVING nazwaZabawki IS NULL

PS.
Pisane z głowy.
Być może zamiast CONCAT powinno byc coś lepszego do agregacji.

Pozdrawiam
Tomek
Re: Zapytanie eliminujące bez podzapytań (master-detail-detail)
#195041
Author: Roman Tyczka
Date: Thu, 14 Jul 2016 18:20
12 lines
1305 bytes
On Thu, 14 Jul 2016 17:28:07 +0200, tomek wrote:

> PS.
> Pisane z głowy.
> Być może zamiast CONCAT powinno byc coś lepszego do agregacji.

Dzięki, to chyba jest dobry trop, jutro to zweryfikuje, bo mam pewien
koncept bazujący na Twojej propozycji.

-- 
pozdrawiam
Roman Tyczka
Re: Zapytanie eliminujące bez podzapytań (master-detail-detail)
#195042
Author: geos
Date: Thu, 14 Jul 2016 20:15
17 lines
1558 bytes
On 13.07.2016 15:22, Roman Tyczka wrote:
> Każde dziecko może mieć kilka zabawek, każdy rodzic kilkoro dzieci.
> Jak za pomocą jednego selecta wydobyć tylko tych rodziców, których dzieci
> nie mają określonych zabawek, np. lalki?

select r.id, r.nm
, sum(decode(z.nm,'LALKA',1,0)) n
from z
join d on z.idd=d.id
join r on d.idr=r.id
group by r.id, r.nm
having sum(decode(z.nm,'LALKA',1,0))=0

na przyszłość podawaj nazwę bazy, z którą pracujesz...

pozdrawiam
geos
Re: Zapytanie eliminujące bez podzapytań (master-detail-detail)
#195044
Author: Roman Tyczka
Date: Fri, 15 Jul 2016 15:06
26 lines
1917 bytes
On Thu, 14 Jul 2016 22:15:25 +0200, geos wrote:

> On 13.07.2016 15:22, Roman Tyczka wrote:
>> Każde dziecko może mieć kilka zabawek, każdy rodzic kilkoro dzieci.
>> Jak za pomocą jednego selecta wydobyć tylko tych rodziców, których dzieci
>> nie mają określonych zabawek, np. lalki?
> 
> select r.id, r.nm
> , sum(decode(z.nm,'LALKA',1,0)) n
> from z
> join d on z.idd=d.id
> join r on d.idr=r.id
> group by r.id, r.nm
> having sum(decode(z.nm,'LALKA',1,0))=0

Właśnie podobny pomysł podsunął tomek, to działa, dzięki :-)
 
> na przyszłość podawaj nazwę bazy, z którą pracujesz...

To był problem uniwersalny, bo czy to byłoby decode() czy case() to już
detal, chciałem rozwiązania nie sklejonego z konkretną platformą przez
użycie jakichś specyficznych czarów.

-- 
pozdrawiam
Roman Tyczka
Re: Zapytanie eliminujące bez podzapytań (master-detail-detail)
#195038
Author: wloochacz
Date: Tue, 19 Jul 2016 14:15
9 lines
1522 bytes
W dniu 2016-07-14 o 14:36, Roman Tyczka pisze:
/ciach/

> CTE nie zmieni działania tylko go opakuje w ładniejszą formę.
Nie masz racji; CTE to nie tylko cukier syntaktyczny, spójrz w plan 
zapytań skoro nie dowierzasz...

-- 
wloochacz
Re: Zapytanie eliminujące bez podzapytań (master-detail-detail)
#195039
Author: Roman Tyczka
Date: Tue, 19 Jul 2016 15:15
11 lines
1462 bytes
On Tue, 19 Jul 2016 16:15:18 +0200, wloochacz wrote:

>> CTE nie zmieni działania tylko go opakuje w ładniejszą formę.
> Nie masz racji; CTE to nie tylko cukier syntaktyczny, spójrz w plan 
> zapytań skoro nie dowierzasz...

Miałem na myśli ten konkretny przypadek, a nie CTE jako takie.

-- 
pozdrawiam
Roman Tyczka
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads