problem z właściwym zapytaniem do bazy
Pawel - 03-08-2007 09:28
problem z właściwym zapytaniem do bazy
Witam
Jak skonstruować zapytanie (bez użycia podzapytań-mało wydajne) w mysql 5 tak aby wybrać dane z tabeli1 i tabeli2,gdzie pole mod jest różne od 50, a polem łączącym jest id.
Struktura tabela1: id int
tabela2: id_tab2 int id int mod int
dane: tabela1 id=1 id=2 id=3
tabela2 id_tab2=10 id_tab2=11 id_tab2=12 id=1 id=2 id=1 mod=50 mod=50 mod=100
Z góry dziękuję za pomoc Pawel
-- Wysłano z serwisu OnetNiusy: http://niusy.onet.pl
=?ISO-8859-2?Q?Adam_P=B3aszczyca?= - 03-08-2007 09:28
On 2 Aug 2007 22:00:27 +0200, "Pawel" <puchkubWYTNIJTO@poczta.onet.pl> wrote:
>Witam > >Jak skonstruować zapytanie (bez użycia podzapytań-mało wydajne) w mysql 5 tak >aby wybrać dane z tabeli1 i tabeli2,gdzie pole mod jest różne od 50, a polem >łączącym jest id. > >Struktura >tabela1: >id int > >tabela2: >id_tab2 int >id int >mod int > > >dane: >tabela1 >id=1 id=2 id=3 > >tabela2 >id_tab2=10 id_tab2=11 id_tab2=12 >id=1 id=2 id=1 >mod=50 mod=50 mod=100
A w czym problem?
Select * from tabela1 join tabela2 on tabela1.id=tabela2.id where tabela2.mod<>50
-- ___________ (R) /_ _______ Adam 'Trzypion' Płaszczyca (+48 502) 122688 ___/ /_ ___ ul. Na Szaniec 23/70, 31-560 Kraków, (012) 3783198 _______/ /_ http://trzypion.oldfield.org.pl/wieliczka/ ___________/ GG: 3524356
puchkubWYTNIJTO@poczta.onet.pl - 04-08-2007 00:03
> >Witam > > > >Jak skonstruować zapytanie (bez użycia podzapytań-mało wydajne) w mysql 5 tak > >aby wybrać dane z tabeli1 i tabeli2,gdzie pole mod jest różne od 50, a polem > >łączącym jest id. > > > >Struktura > >tabela1: > >id int > > > >tabela2: > >id_tab2 int > >id int > >mod int > > > > > >dane: > >tabela1 > >id=1 id=2 id=3 > > > >tabela2 > >id_tab2=10 id_tab2=11 id_tab2=12 > >id=1 id=2 id=1 > >mod=50 mod=50 mod=100 > > A w czym problem? > > Select * from > tabela1 join tabela2 on tabela1.id=tabela2.id > where tabela2.mod<>50 > Dzięki za zainteresowanie ale właśnie w tym problem że przy tym zapytaniu zostanie mi id=1 a w tabeli2 dla id=1 mam również mod=50. Chciałbym żeby zwróciło mi wszystkie id z tabeli1, które nie mają mod=50 w tabeli2, czy jest jakiś prosty i szybki sposób?
Pozdrawiam Pawel
-- Wysłano z serwisu OnetNiusy: http://niusy.onet.pl
=?ISO-8859-2?Q?Adam_P=B3aszczyca?= - 04-08-2007 00:03
On 3 Aug 2007 13:53:44 +0200, puchkubWYTNIJTO@poczta.onet.pl wrote:
>Dzięki za zainteresowanie ale właśnie w tym problem że przy tym zapytaniu >zostanie mi id=1 a w tabeli2 dla id=1 mam również mod=50. Chciałbym żeby >zwróciło mi wszystkie id z tabeli1, które nie mają mod=50 w tabeli2, czy jest >jakiś prosty i szybki sposób?
A, czyli chodzi o wyselekcjonowanie z tabela1 tylko tych wierszy, dla których nie występuje w tabela2 mod=50? -- ___________ (R) /_ _______ Adam 'Trzypion' Płaszczyca (+48 502) 122688 ___/ /_ ___ ul. Na Szaniec 23/70, 31-560 Kraków, (012) 3783198 _______/ /_ http://trzypion.oldfield.org.pl/wieliczka/ ___________/ GG: 3524356
puchkubWYTNIJTO@poczta.onet.pl - 04-08-2007 00:03
> On 3 Aug 2007 13:53:44 +0200, puchkubWYTNIJTO@poczta.onet.pl wrote: > > >Dzięki za zainteresowanie ale właśnie w tym problem że przy tym zapytaniu > >zostanie mi id=1 a w tabeli2 dla id=1 mam również mod=50. Chciałbym żeby > >zwróciło mi wszystkie id z tabeli1, które nie mają mod=50 w tabeli2, czy jest > >jakiś prosty i szybki sposób? > > A, czyli chodzi o wyselekcjonowanie z tabela1 tylko tych wierszy, dla > których nie występuje w tabela2 mod=50? > --
TAK
Przepraszam za mój pokrętny opis problemu.
-- Wysłano z serwisu OnetNiusy: http://niusy.onet.pl
=?ISO-8859-2?Q?Adam_P=B3aszczyca?= - 04-08-2007 00:03
On 3 Aug 2007 15:37:20 +0200, puchkubWYTNIJTO@poczta.onet.pl wrote:
>> A, czyli chodzi o wyselekcjonowanie z tabela1 tylko tych wierszy, dla >> których nie występuje w tabela2 mod=50? > >TAK
Hm.. może tak:
select * from tabela1 where not exist (select * from tabela2 where tabela1.id=tabela2.id and tabela2=50) -- ___________ (R) /_ _______ Adam 'Trzypion' Płaszczyca (+48 502) 122688 ___/ /_ ___ ul. Na Szaniec 23/70, 31-560 Kraków, (012) 3783198 _______/ /_ http://trzypion.oldfield.org.pl/wieliczka/ ___________/ GG: 3524356
Hubert - 04-08-2007 00:03
Adam Płaszczyca wrote: > select * from tabela1 > where not exist (select * from tabela2 where tabela1.id=tabela2.id and > tabela2=50)
Przecież prosił bez podzapytań...
Hubert - 04-08-2007 00:03
puchkubWYTNIJTO@poczta.onet.pl wrote: >> On 3 Aug 2007 13:53:44 +0200, puchkubWYTNIJTO@poczta.onet.pl wrote: >> >>> Dzięki za zainteresowanie ale właśnie w tym problem że przy tym zapytaniu >>> zostanie mi id=1 a w tabeli2 dla id=1 mam również mod=50. Chciałbym żeby >>> zwróciło mi wszystkie id z tabeli1, które nie mają mod=50 w tabeli2, czy jest >>> jakiś prosty i szybki sposób? >> A, czyli chodzi o wyselekcjonowanie z tabela1 tylko tych wierszy, dla >> których nie występuje w tabela2 mod=50? >> -- > > > TAK > A możesz sobie pozwolić na zrobienie tego 2 zapytaniami, przy czym drugie utworzone poza bazą na podstawie danych uzyskanych z pierwszego zapytania? Wtedy listę wartości dla NOT IN wygenerowałbyś sobie sam w PHP, Javie czy w czym tam to robisz, bo zakładam, że Twoim problemem jest to (tyle, że u Ciebie NOT IN):
"An implication is that an IN subquery can be much slower than a query written using an IN(value_list) construct that lists the same values that the subquery would return."
puchkubWYTNIJTO@poczta.onet.pl - 04-08-2007 00:03
> puchkubWYTNIJTO@poczta.onet.pl wrote: > >> On 3 Aug 2007 13:53:44 +0200, puchkubWYTNIJTO@poczta.onet.pl wrote: > >> > >>> Dzięki za zainteresowanie ale właśnie w tym problem że przy tym zapytaniu > >>> zostanie mi id=1 a w tabeli2 dla id=1 mam również mod=50. Chciałbym żeby > >>> zwróciło mi wszystkie id z tabeli1, które nie mają mod=50 w tabeli2, czy jest > >>> jakiś prosty i szybki sposób? > >> A, czyli chodzi o wyselekcjonowanie z tabela1 tylko tych wierszy, dla > >> których nie występuje w tabela2 mod=50? > >> -- > > > > > > TAK > > > A możesz sobie pozwolić na zrobienie tego 2 zapytaniami, przy czym > drugie utworzone poza bazą na podstawie danych uzyskanych z pierwszego > zapytania? Wtedy listę wartości dla NOT IN wygenerowałbyś sobie sam w > PHP, Javie czy w czym tam to robisz, bo zakładam, że Twoim problemem > jest to (tyle, że u Ciebie NOT IN): > > "An implication is that an IN subquery can be much slower than a query > written using an IN(value_list) construct that lists the same values > that the subquery would return." >
Podzapytania i NOT IN są bardzo wolne a jak dojdą do tego jeszcze łączenia z innych tabel to zapytanie potrafi wykonywać mi się 3 minuty więc nie jest to dopuszczalne. Myślałem że ktoś podpowie mi coś z dziedziny procedur zapamiętanych?
Oczywiście że mogę rozdzielić zapytanie na 2 i oprogramować, ale i tutaj pojawia się pytanie: 1. w pierwszym zapytaniu wybrać dane z tabeli1, a w drugim zapytaniu z tabeli2 wybrać rekordy których nie chcemy w tabeli1. zapisać dane do zmiennych i w pętli porównywać i wyrzucać z tabeli1? 2. gigantyczne zapytanie z danymi z tabeli2 w warunku wybierającym dane z tabeli1, czyli select tabela1.* from tabela1 where id<>1 and id<>2 i tak dalej przez wszystkie wartości id z niechcianych danych.?
Mam wielkie obawy co do obydwu rozwiązań. Ma ktoś jakiś sensowny pomysł na rozwiązanie tego problemu?
Pozdrawiam Pawel
-- Wysłano z serwisu OnetNiusy: http://niusy.onet.pl
=?ISO-8859-2?Q?Pawe=B3_Matejski?= - 04-08-2007 00:03
puchkubWYTNIJTO@poczta.onet.pl wrote: > > Podzapytania i NOT IN są bardzo wolne a jak dojdą do tego jeszcze łączenia z > innych tabel to zapytanie potrafi wykonywać mi się 3 minuty więc nie jest to > dopuszczalne.
Wielokrotnie tu pisałem, jak taki problem rozwiązać prostym zapytaniem wykorzystując HAVING, COUNT i CASE. Przeszukaj archiwum.
> Myślałem że ktoś podpowie mi coś z dziedziny procedur zapamiętanych?
Nie ma sensu angażować w to procedur...
-- P.M.
Hubert - 04-08-2007 00:03
puchkubWYTNIJTO@poczta.onet.pl wrote: > Mam wielkie obawy co do obydwu rozwiązań. Ma ktoś jakiś sensowny pomysł na > rozwiązanie tego problemu?
To może inaczej jeszcze... Takie coś spróbuj:
SELECT newid, id2, `mod` FROM (
SELECT id AS newid FROM (
SELECT id FROM t1 UNION ALL (
SELECT id FROM t2 WHERE `mod` =50 ) ) AS alias GROUP BY newid HAVING count( * ) <=1 ) AS alias2, t2 WHERE alias2.newid = t2.id
Oczywiście przy założeniu, że t1.id jest unikalne. Co prawda podzapytań nie brakuje, ale wydaje mi się (mogę być w błędzie), ze nie wszystkie są wolno obsługiwane, tylko te w IN/ANY itp.
puchkubWYTNIJTO@poczta.onet.pl - 05-08-2007 00:05
> puchkubWYTNIJTO@poczta.onet.pl wrote: > > Mam wielkie obawy co do obydwu rozwiązań. Ma ktoś jakiś sensowny pomysł na > > rozwiązanie tego problemu? > > To może inaczej jeszcze... > Takie coś spróbuj: > > SELECT newid, id2, `mod` > FROM ( > > SELECT id AS newid > FROM ( > > SELECT id > FROM t1 > UNION ALL ( > > SELECT id > FROM t2 > WHERE `mod` =50 > ) > ) AS alias > GROUP BY newid > HAVING count( * ) <=1 > ) AS alias2, t2 WHERE alias2.newid = t2.id > > Oczywiście przy założeniu, że t1.id jest unikalne. Co prawda podzapytań > nie brakuje, ale wydaje mi się (mogę być w błędzie), ze nie wszystkie są > wolno obsługiwane, tylko te w IN/ANY itp.
Podane zapytanie zadziałało prawidłowo i szybciej od mojego pierwotnego z NOT IN ale i tak czas wykonywania był około 22 s., a więc nie dopuszczalny. W archiwum znalazłem odpowiedź na podobny post pana Pawła Matejskiego i w moim przypadku zapytanie będzie wyglądało tak:
select tab1.id from tab1,tab2 where tab1.id = tab2.id group by tab1.id having count(*) = sum(case when `mod` != 50 then 1 else 0 end)
czas wykonania jest poniżej 1 s. Bardzo dziękuje wszystkim za pomoc.
Pawel
-- Wysłano z serwisu OnetNiusy: http://niusy.onet.pl
puchkub@poczta.onet.pl - 05-08-2007 00:05
> puchkubWYTNIJTO@poczta.onet.pl wrote: > > > > Podzapytania i NOT IN są bardzo wolne a jak dojdą do tego jeszcze łączenia z > > innych tabel to zapytanie potrafi wykonywać mi się 3 minuty więc nie jest to > > dopuszczalne. > > Wielokrotnie tu pisałem, jak taki problem rozwiązać prostym zapytaniem > wykorzystując HAVING, COUNT i CASE. Przeszukaj archiwum. > > > Myślałem że ktoś podpowie mi coś z dziedziny procedur zapamiętanych? > > Nie ma sensu angażować w to procedur... > > -- > P.M.
Bardzo dziękuje z podpowiedź. Pozdrawiam Pawel
-- Wysłano z serwisu OnetNiusy: http://niusy.onet.pl
zanotowane.pldoc.pisz.plpdf.pisz.pleffulla.pev.pl
|
Oracle, SQL, PL/SQL. Jak =?ISO-8859-2?Q?napisa=E6_zapytanie=2C?==?ISO-8859-2?Q?_kt=F3re_zwr=F3ci_nazw=EA_atrybutu=2C_kt=F3reg o?==?ISO-8859-2?Q?_warto=B6ci_spe=B3niaj=B1_zadany_warunek?=
=?ISO-8859-2?Q?Narz=EAdzie_do_budowania_zapyta=F1_SQL=2C?==?I SO-8859-2?Q?_PL/PgSQL=2C_PL/SQL=2C_T-SQL?=
[ms sql] =?ISO-8859-2?Q?wy=B6wietlenie_pierwszych_5_rekord?==?ISO-8859-2?Q?=F3w_z_zapytania_=3F_odpowiednik_ROWNUM_w_o?== ?ISO-8859-2?Q?raclu_dla_MS_SQL=27a?=
mysql i mysql-front, problem
String line; if (line=="cos"){...}....problem
Problemy z =?ISO-8859-2?Q?instalacj=B1_PostgreSQL_na_syste?==?ISO-8859-2?Q?mach_Windows?=
[postgres] Problem z =?ISO-8859-2?Q?zmian=B1_struktury_i_z?==?ISO-8859-2?Q?ale=BFno=B6ciami=2E?=
[oracle] =?ISO-8859-2?Q?zmia=BFd=BFony_przez_problem=3A_za?==?ISO-8859-2?Q?pytanie_do_hierarchi?=
phpMyAdmin zadaje =?ISO-8859-2?Q?z=B3e_zapytania=2E=2E=2E_Dl?==?ISO-8859-2?Q?aczego=3F?=
[mysql 5.x] jak =?ISO-8859-2?Q?zrealizowa=E6_zapytanie=3F_cz?==?ISO-8859-2?Q?yli_podzapytanie_i_wi=EAcej_ni=BF_jeden_rz=B1? ==?ISO-8859-2?Q?d_wynik=F3w?=
zanotowane.pldoc.pisz.plpdf.pisz.plmarcelq.xlx.pl
Cytat
Decede mihi sole - nie zasłaniaj mi słonca. Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści Hoc fac - tak czyń. A tergo - od tyłu; z tyłu. I czarne włosy posiwieją. Safona |
|