<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
	<channel>
		<title><![CDATA[Forum PostgreSQL - porównanie wartości z dwóch tabel przy użyciu pythona]]></title>
		<link>https://forum.postgresql.org.pl/viewtopic.php?id=1921</link>
		<description><![CDATA[Najświeższe odpowiedzi w porównanie wartości z dwóch tabel przy użyciu pythona.]]></description>
		<lastBuildDate>Wed, 11 Dec 2013 10:13:36 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Odp: porównanie wartości z dwóch tabel przy użyciu pythona]]></title>
			<link>https://forum.postgresql.org.pl/viewtopic.php?pid=4916#p4916</link>
			<description><![CDATA[Zadałem pytanie na ircu, i na liście mailingowej. Zobaczymy czy będzie odzew. Realnie - trzeba by pewnie zajrzeć mocno do kodu sortującego. Na liście pojawiła się sugestia, że może to być związane z ilością rekordów. RhodiumToad pokazał, że jak skasuje się rekord (1,1), to wyniki się zmieniają (jak się zmieni kolejność subselectów w unionie).

Tak czy inaczej - zgadzam się z ludźmi z irca - wnikanie ma pewien sens jako "gra umysłowa", ale wtedy trzeba samemu usiąść ze źródłami, debuggerem i piwem. Aż tak mi się nie nudzi :)]]></description>
			<author><![CDATA[dummy@example.com (depesz)]]></author>
			<pubDate>Wed, 11 Dec 2013 10:13:36 +0000</pubDate>
			<guid>https://forum.postgresql.org.pl/viewtopic.php?pid=4916#p4916</guid>
		</item>
		<item>
			<title><![CDATA[Odp: porównanie wartości z dwóch tabel przy użyciu pythona]]></title>
			<link>https://forum.postgresql.org.pl/viewtopic.php?pid=4915#p4915</link>
			<description><![CDATA[Co do finalnego zapytania to masz 100% racji, ale swoją drogą ciekawe zachowanie bazy :)]]></description>
			<author><![CDATA[dummy@example.com (c_michal)]]></author>
			<pubDate>Wed, 11 Dec 2013 09:55:15 +0000</pubDate>
			<guid>https://forum.postgresql.org.pl/viewtopic.php?pid=4915#p4915</guid>
		</item>
		<item>
			<title><![CDATA[Odp: porównanie wartości z dwóch tabel przy użyciu pythona]]></title>
			<link>https://forum.postgresql.org.pl/viewtopic.php?pid=4914#p4914</link>
			<description><![CDATA[@c_michal:

Szczerze mówiąc nie jestem pewien czemu to działa tak jak działa dla 2004/2005.

Ogólnie - jeśli nie sortujesz wyniku po jakimś polu, to baza danych może zwrócić "losowy" wynik. Dlaczego dla tego zapytania akurat zawsze zwraca mniejszą wartość - trzeba by poszukać w kodzie, ale to nie ma za bardzo sensu - i tak nie można by na takiej "logice" polegać, bo zawsze może być zmieniona.

Natomiast co do finalnego zapytania - podwójne sortowanie nie daje gwarancji. Lepiej:

[code]
with rok2004 (miesiac,wynik) as (values (1,1),(2,2)      ,(4,4),(5,null),(6,6))
    ,rok2005 (miesiac,wynik) as (values (1,3)      ,(3,3),(4,5)         ,(6,6))
select
    distinct on (miesiac) *
from (
    select miesiac, 2004 as rok, wynik from rok2004
    union all
    select miesiac, 2005 as rok, wynik from rok2005
) as polaczone
order by miesiac, wynik desc, rok asc;
[/code]]]></description>
			<author><![CDATA[dummy@example.com (depesz)]]></author>
			<pubDate>Wed, 11 Dec 2013 09:49:52 +0000</pubDate>
			<guid>https://forum.postgresql.org.pl/viewtopic.php?pid=4914#p4914</guid>
		</item>
		<item>
			<title><![CDATA[Odp: porównanie wartości z dwóch tabel przy użyciu pythona]]></title>
			<link>https://forum.postgresql.org.pl/viewtopic.php?pid=4908#p4908</link>
			<description><![CDATA[Bardzo mi się spodobała "alternatywa" pokazana jako rozwiązanie zaproponowane przez depesza chodzi mi dokładnie o:
[quote=depesz]select
    distinct on (miesiac) *
from (
    select miesiac, 2004 as rok, wynik from rok2004
    union all
    select miesiac, 2005 as rok, wynik from rok2005
) as polaczone
order by miesiac, wynik desc;[/quote]

Rozwiązanie mnie bardzo wciągnęło, bo uważałem, że nie może dobrze działać dla przypadku gdy pole wynik przyjmie taką samą wartość dla roku 2004 i 2005 (zwrot [b]nie może[/b] należy rozumieć jako pewną moją skłonność do szeregowania danych, ja osobiście wolał bym by gdy dla jakiegoś miesiąca wartości są równe w obu latach to by w wyniku pokazał mi się młodszy rok).

i tu nastąpił pewien problem, którego nie mogę zrozumieć może depesz by mnie oświecił jak działa optymalizator w takim wypadku. Wielokrotnie bawiłem się tym zapytaniem zmieniając dane wejściowe wykonując takie zapytanie:

with rok2005 (miesiac,wynik) as (values (1,1),(2,2)      ,(4,4),(5,null),(6,6))
    ,rok2004 (miesiac,wynik) as (values (1,3)      ,(3,3),(4,5)         ,(6,6))
select
    distinct on (miesiac) *
from (
    select miesiac, 2004 as rok, wynik from rok2004
    union all
    select miesiac, 2005 as rok, wynik from rok2005
) as polaczone
order by miesiac, wynik desc;

za każdym razem dostawałem prawidłowe wyniki mimo że wykonywałem je też w takiej formie (co powinno zmienić rok w wyniku dla czerwca):
with rok2004 (miesiac,wynik) as (values (1,1),(2,2)      ,(4,4),(5,null),(6,6))
    ,rok2005 (miesiac,wynik) as (values (1,3)      ,(3,3),(4,5)         ,(6,6))
select
    distinct on (miesiac) *
from (
    select miesiac, 2004 as rok, wynik from rok2004
    union all
    select miesiac, 2005 as rok, wynik from rok2005
) as polaczone
order by miesiac, wynik desc;

niestety nic takiego nie miało miejsca aż do chwili gdy do uniona analogicznie jak wyżej dodałem union z rokiem 2006. 
Od tego momentu zapytania (powyżej) zaczęły zwracać inne wyniki. 
I tu moje pytanie do depesza jak postgres sobie z tym radzi (musi jakoś buforować wyniki zapytań ale jak, co dokładnie robi optymalizator)

PS
Moim zdaniem to zapytanie (tak by spełniało moje wymagania) powinno wyglądać tak:

with rok2004 (miesiac,wynik) as (values (1,1),(2,2)      ,(4,4),(5,null),(6,6))
    ,rok2005 (miesiac,wynik) as (values (1,3)      ,(3,3),(4,5)         ,(6,6))
select
    distinct on (miesiac) *
from (
    select miesiac, 2004 as rok, wynik from rok2004
    union all
    select miesiac, 2005 as rok, wynik from rok2005
    order by miesiac,rok
) as polaczone
order by miesiac, wynik desc;]]></description>
			<author><![CDATA[dummy@example.com (c_michal)]]></author>
			<pubDate>Tue, 10 Dec 2013 22:54:36 +0000</pubDate>
			<guid>https://forum.postgresql.org.pl/viewtopic.php?pid=4908#p4908</guid>
		</item>
		<item>
			<title><![CDATA[Odp: porównanie wartości z dwóch tabel przy użyciu pythona]]></title>
			<link>https://forum.postgresql.org.pl/viewtopic.php?pid=4895#p4895</link>
			<description><![CDATA[Python wydaje mi się nieistotny. Można to zrobić prostym zapytaniem. Jedną wersję podał c_michał. Możesz jeszcze na co najmniej dwa sposoby:

[code]
insert into wyniki (miesiac, rok, wynik)
select
    coalesce( r4.miesiac, r5.miesiac),
    case when coalesce(r4.wynik,0)>=coalesce(r5.wynik,0) then 2004 else 2005 end,
    case when coalesce(r4.wynik,0)>=coalesce(r5.wynik,0) then r4.wynik else r5.wynik end
from
    rok2004 as r4
    full outer join rok2005 as r5 using (miesiac)
[/code]

To jest modyfikacja pomysłu c_michała. Należy tylko mieć świadomość faktu, że nie nie zadziała poprawnie jeśli możesz mieć ujemne wyniki.

Alternatywa:

[code]
insert into wyniki (miesiac, rok, wynik)
select
    distinct on (miesiac) *
from (
    select miesiac, 2004 as rok, wynik from rok2004
    union all
    select miesiac, 2005 as rok, wynik from rok2005
) as polaczone
order by miesiac, wynik desc;
[/code]]]></description>
			<author><![CDATA[dummy@example.com (depesz)]]></author>
			<pubDate>Tue, 10 Dec 2013 11:05:00 +0000</pubDate>
			<guid>https://forum.postgresql.org.pl/viewtopic.php?pid=4895#p4895</guid>
		</item>
		<item>
			<title><![CDATA[Odp: porównanie wartości z dwóch tabel przy użyciu pythona]]></title>
			<link>https://forum.postgresql.org.pl/viewtopic.php?pid=4891#p4891</link>
			<description><![CDATA[niestety nie znal pythona ale samo rozwiązanie można zrealizować tak:
INSERT INTO wyniki (miesiac,rok,wynik)
select 
  miesiac.miesiac
, case when coalesce(r4.wynik,0)>=coalesce(r5.wynik,0) then 2004 else 2005 end as rok 
, case when coalesce(r4.wynik,0)>=coalesce(r5.wynik,0) then r4.wynik else r5.wynik end as wynik 
from generate_series(1,12) miesiac
left join rok2004 r4 on miesiac.miesiac=r4.miesiac
left join rok2005 r5 on miesiac.miesiac=r5.miesiac;]]></description>
			<author><![CDATA[dummy@example.com (c_michal)]]></author>
			<pubDate>Mon, 09 Dec 2013 21:48:02 +0000</pubDate>
			<guid>https://forum.postgresql.org.pl/viewtopic.php?pid=4891#p4891</guid>
		</item>
		<item>
			<title><![CDATA[porównanie wartości z dwóch tabel przy użyciu pythona]]></title>
			<link>https://forum.postgresql.org.pl/viewtopic.php?pid=4880#p4880</link>
			<description><![CDATA[Witam, mam problem ze zrobieniem zadania na zajęcia. Mam dwie tabele rok2004 i rok2005, w każdej jest miesiąc jako int i wynik, i muszę porównać te wyniki i w zależności który jest większy wpisać do trzeciej tabeli wraz z numerem miesiąca i rokiem. Zrobiłam coś takiego:

CREATE OR REPLACE FUNCTION compare()
  RETURNS trigger AS
$BODY$CREATE OR REPLACE FUNCTION increment(i integer = 1) RETURNS integer AS $$
        BEGIN
        i=1
        while i<13:
                a=(select wynik from rok2004 where miesiac = 'i')
                b=(select wynik from rok2005 where miesiac = 'i')
                if a>b:
			INSERT INTO wyniki values (i, 2004, (select wynik from rok2004 where miesiac = i)
		else:
			INSERT INTO wyniki values (i, 2005, (select wynik from rok2005 where miesiac = i)
        END;
$$ LANGUAGE plpythonu;

Zapytanie wykonuje się, nie wyrzuca błędów ale też w tabeli wyniki nadal jest pusto. Ktoś wie co mogę z tym zrobić? Jak poprawić?]]></description>
			<author><![CDATA[dummy@example.com (warpath)]]></author>
			<pubDate>Mon, 09 Dec 2013 18:04:21 +0000</pubDate>
			<guid>https://forum.postgresql.org.pl/viewtopic.php?pid=4880#p4880</guid>
		</item>
	</channel>
</rss>
