Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Znowu left joiny
Forum PHP.pl > Forum > Bazy danych
kasztan
Cześć,
kolejny dzień ślęczenia nad zapytaniem i nic.
Wątek http://forum.php.pl/viewtopic.php?t=6692 przestudiowałem dość szczegółowo i nie potrafiłem zrobić swojego zapytania.

Mam 3 table: agenci, firmy, produkty. Chcę zliczyć ile każdy agent pozyskał produktów i firm. Nie będę rozpisywał poszczególnych atrybutów dla każdej z tabel. Wszystko widać z zapytań.
Może jednak nie widać, bo coś się nie mogę doczekać odpowiedzi. Więc powiem tylko te najważniejsze:
agents_pl: agent_id
firms_pl_transact: firm_id, agent_id
products_pl_transact: product_id, firm_id, agent_id.

Zapytanie o liczbę firm wygląda tak i działa o.k.:
[sql:1:b467487e3b]
select a.firstname 'Imię', a.lastname 'Nazwisko', count(f.agent_id) as 'Liczba firm'
from agents_pl a
left join firms_pl_transact f on (a.agent_id = f.agent_id)
WHERE
a.active_i = 1
AND
a.agent_id not in (1, 2)
group by a.agent_id
order by 'Liczba firm' desc, a.lastname;
[/sql:1:b467487e3b]

Analogicznie zapytanie o liczbę produktów wygląda tak i działa o.k.:
[sql:1:b467487e3b]
select a.firstname 'Imię', a.lastname 'Nazwisko', count(p.agent_id) as 'Liczba produktów'
from agents_pl a
left join products_pl_transact p on (a.agent_id = p.agent_id)
WHERE
a.active_i = 1
AND
a.agent_id not in (1, 2)
group by a.agent_id
order by 'Liczba produktów' desc, a.lastname;
[/sql:1:b467487e3b]

No i teraz potrzebuję zapytania, które da mi sumę tych firm i produktów.
Niestety w tej postaci, jak poniżej, dostaję co prawda jakieś wyniki, ale są bzdurne.
[sql:1:b467487e3b]
select a.firstname 'Imię', a.lastname 'Nazwisko', count(p.agent_id) + count(f.agent_id) as 'Liczba umów'
from agents_pl a
left join products_pl_transact p on (a.agent_id = p.agent_id)
left join firms_pl_transact f on (a.agent_id = f.agent_id)
WHERE
a.active_i = 1
AND
a.agent_id not in (1, 2)
group by a.agent_id
order by 'Liczba umów' desc, a.lastname
[/sql:1:b467487e3b]

Help me.
kasztan
Hmm, czy naprawdę nikt nie może mi pomóc :?:
uboottd
Jedno zapytanie tylko z left joinami bedzie bardzo kulawe o ile nie niemozliwe. To akurat dobry przyklad na wykorzystanie podzapytan - grupowanie po roznych kryteriach.
kasztan
A może by tak jakaś konkretniejsza podpowiedź jak mam to zrobic?
chfast
Cytat
A może by tak jakaś konkretniejsza podpowiedź jak mam to zrobic?

A może jakieś bardziej zrozumiałe pytanie?
Cytat
potrzebuję zapytania, które da mi sumę tych firm i produktów

Nie rozumiem o co ci chodzi. Jak dla mnie to wychodzi tak:
liczba produktów: a
liczba firm: b
"suma tych firm i produktów": a + b .
kasztan
Cytat
A może jakieś bardziej zrozumiałe pytanie?

Sorry, ale wydaje mi się, że się wyraziłem dość precyzjnie.

Cytat
Nie rozumiem o co ci chodzi. Jak dla mnie to wychodzi tak:
liczba produktów: a
liczba firm: b
"suma tych firm i produktów": a + b .

Tak, o to mi chodzi, ale mam to mieć w jednym zapytaniu! To że działa dla każdego z osobna, to mi w zasadzie niewiele daje.
durzy
sprobuj uzyc UNION pomiedzy pierwszym kodem a drugim i w pierwszym usun sortowanie

Pozdrawiam
kasztan
Cytat
sprobuj uzyc UNION pomiedzy pierwszym kodem a drugim i w pierwszym usun sortowanie

Pozdrawiam


Tak, tylko, że zauważ, że mam w obu tych zapytaniach grupowanie i sortowanie, a jak zrobię union tych dwóch zapytań, to jak mam to pogrupować i posortować?? Jak zrobię grupowanie tak, jak jest (czyli 2 razy, to w wyniku dostanę co prawda poprawne wyniki, ale będzie się wynik składał z 2 części (najpierw wyświetleni zostaną wszyscy z pierwszego zapytania, a potem z drugiego, a ja chcę dostać jeden wynik, który będzie zawierał sumę).
durzy
oki - moze bredze ale juz jestem po kilku godzinach pracy i jestem zmeczony.
probowalem "zobaczyc" Twoje tablice i mam kilka pytan:

1) dlaczego piszesz w select'cie
[sql:1:3461983a7c]SELECT a.firstname 'Imię', a.lastname 'Nazwisko'[/sql:1:3461983a7c]
czy te dwa pola maja byc osobno? czy nie lepiej napisac
[sql:1:3461983a7c]SELECT (a.firstname+' '+a.lastname) 'Imie i Nazwisko'[/sql:1:3461983a7c]

2) czy grupowanie jest napewno zrobione dobrze?
imho powinienes zrobic grupowanie po a.firstname, a.lastname lub
(a.firstname+' '+a.lastname) w obu przypadkach?

pozdrawiam
kasztan
Cytat
...
1) dlaczego piszesz w select'cie
[sql:1:7d7708ca46]SELECT a.firstname 'Imię', a.lastname 'Nazwisko'[/sql:1:7d7708ca46]
czy te dwa pola maja byc osobno? czy nie lepiej napisac
[sql:1:7d7708ca46]SELECT (a.firstname+' '+a.lastname) 'Imie i Nazwisko'[/sql:1:7d7708ca46]


Lepiej, nie lepiej, potrzebowałem je "oddzielnie" smile.gif. Nie wpływa to w żaden sposób na sposób rozwiązania.


Cytat
2) czy grupowanie jest napewno zrobione dobrze?
imho powinienes zrobic grupowanie po a.firstname, a.lastname lub
(a.firstname+' '+a.lastname) w obu przypadkach?
...


Generalnie musiałem po czymś grupować, ponieważ w warunku selekcji użyłem funkcji agregującej count (bez count'a wyrzuca błąd - to na wypadek jakby ktoś pytał dlaczego musi być grupowanie).
A czy nie powiniem grupować po czymś innym (a.firstname, a.lastname, tak jak proponowałeś)? - raczej nie, bo jeśli bym grupował tak, jak piszesz, to tym razem dostanę 4 "porcje wyników" (grupowanie po imieniu z 1 zapytania, grupowanie po nazwisku z 1 zapytania, grupowanie po imieniu z 2 zapytania, grupowanie po nazwisku z 2 zapytania).
Rozwiązanie musi być gdzieś blisko, ale gdzie? biggrin.gif
durzy
szkoda ze nie napisales pod czym piszesz te zapytania. wnioskuje ze srednikow znajdujacych sie w kodzie ze jest to (chyba) mysql.

ja pracuje na mssql i Twoj problem mozna na tym rozwiazac bardzo szybko poprzez takie zapytanie:
[sql:1:0fb472fd77]
SELECT t.firstname, t.lastname, sum(t.liczba) 'Liczba produktow + umow'
FROM (SELECT a.firstname, a.lastname, count(f.agent_id) 'Liczba'
FROM agents_pl a
LEFT join firms_pl_transact f ON (a.agent_id = f.agent_id)
WHERE a.active_i = 1
AND a.agent_id NOT in (1, 2)
GROUP BY a.firstname, a.lastname,a.agent_id
UNION
SELECT a.firstname, a.lastname, count(p.agent_id) 'Liczba'
FROM agents_pl a
LEFT join products_pl_transact p ON (a.agent_id = p.agent_id)
WHERE a.active_i = 1
AND a.agent_id NOT in (1, 2)
GROUP BY a.firstname, a.lastname,a.agent_id
) t
GROUP BY t.firstname, t.lastname
ORDER BY 3 desc, 1
[/sql:1:0fb472fd77]

wydaje mi sie ze mysql obsluguje juz podzapytania. jesli nie to chyba bedziesz jednak musial to rozbic na 2 select'y

Pozdrawiam
kasztan
Cytat
szkoda ze nie napisales pod czym piszesz te zapytania. wnioskuje ze srednikow znajdujacych sie w kodzie ze jest to (chyba) mysql.

tak, MySql

Cytat
wydaje mi sie ze mysql obsluguje juz podzapytania. jesli nie to chyba bedziesz jednak musial to rozbic na 2 select'y
Pozdrawiam


Niestety, otrzymuje taki komunikat o błędzie, w sumie nie wiem, czy to jest wina błędnego zapytania, czy tego, że wersja MySql'a na której pracuję (4.0.14) nie obsługuje podzapytań.

Kod
You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT a.firstname, a.lastname, count(f.agent_id) 'Liczba' FRO
uboottd
Mysql podzapytania obsluguje od wersji 4.1, jednakze jest to wersja poki co alfa. Produkcyjne 4.0.x nie obsluguja podzapytan.

Dlaczego nie mozesz miec tego w dwoch zapytaniach i zsumowac to tam gdzie wywolujesz ?

Co do union - zapytania zlaczone unionem moga miec rozne grupowania, tylko sortowanie jest wspolne dla calej uni, ale to tez niewiele ci da.

W zasadzie jedynym wyjscie jest tabela tymczasowa. Robisz to mniej wiecej tak:
1. CREATE TEMPORARY TABLE t(potrzebne pola)
2. INSERT INTO t SELECT <ten pierwszy select>
3. SELECT <ten drugi select, ale z doklejona tabela t>
4. DROP TABLE t
kasztan
Cytat
Mysql podzapytania obsluguje od wersji 4.1, jednakze jest to wersja poki co alfa. Produkcyjne 4.0.x nie obsluguja podzapytan.

Dlaczego nie mozesz miec tego w dwoch zapytaniach i zsumowac to tam gdzie wywolujesz ?


Hmm, więc jednak z podzapytaniami się nie da. A co do rozwiązania podanego przez Ciebie, to już dawno coś musiałem wymyśleć, bo potrzebowałem, żeby to zrobić. Jednak przy moim rozwiązaniu nie tworzę tymczasowej tabeli w bazie, tylko wyniki obu zapytań zapisuję w tablicy w php'ie, potem ładnie sortuję tą tablicę po jednym z jej wymiarów i odczytuję dane.
Z tym, że przy tym rozwiązaniu napotkałem kolejny problem. Otóż mam tablicę:
[php:1:098d87ff23]
<?php
$tab3 = array("id", "imie", "nazwisko", "ile_razem");
?>
[/php:1:098d87ff23]
a w niej mam zapisane to, co odczytałem przy pomocy tych moich 2 zapytań, pole ile_razem to jest suma tego co odczytałem z pierwszego zapytania i tego, co odczytałem z drugiego zapytania.
Teraz, żeby ładnie wyświetlić dane z tej tablicy muszę posortować tą tablicę.
[php:1:098d87ff23]
<?php
array_multisort($tab3["ile_razem"], SORT_DESC, SORT_NUMERIC, $tab3["id"], $tab3["imie"], $tab3["nazwisko"]);
?>
[/php:1:098d87ff23]
I tu się pojawia pewien problem, bo o ile są różne wartości w ile_razem, to wszystko jest o.k., to kiedy kilku agentów ma taką samą wartość ile_razem, to chciałbym, żeby wówczas ta tablica była posortowana wg nazwiska. Jak to zrobić?
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.