<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Forum PostgreSQL - porównanie wartości z dwóch tabel przy użyciu pythona]]></title>
	<link rel="self" href="http://forum.postgresql.org.pl/extern.php?action=feed&amp;tid=1921&amp;type=atom"/>
	<updated>2013-12-11T10:13:36Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.postgresql.org.pl/viewtopic.php?id=1921</id>
		<entry>
			<title type="html"><![CDATA[Odp: porównanie wartości z dwóch tabel przy użyciu pythona]]></title>
			<link rel="alternate" href="https://forum.postgresql.org.pl/viewtopic.php?pid=4916#p4916"/>
			<content type="html"><![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 :)]]></content>
			<author>
				<name><![CDATA[depesz]]></name>
				<uri>https://forum.postgresql.org.pl/profile.php?id=1564</uri>
			</author>
			<updated>2013-12-11T10:13:36Z</updated>
			<id>https://forum.postgresql.org.pl/viewtopic.php?pid=4916#p4916</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Odp: porównanie wartości z dwóch tabel przy użyciu pythona]]></title>
			<link rel="alternate" href="https://forum.postgresql.org.pl/viewtopic.php?pid=4915#p4915"/>
			<content type="html"><![CDATA[Co do finalnego zapytania to masz 100% racji, ale swoją drogą ciekawe zachowanie bazy :)]]></content>
			<author>
				<name><![CDATA[c_michal]]></name>
				<uri>https://forum.postgresql.org.pl/profile.php?id=627</uri>
			</author>
			<updated>2013-12-11T09:55:15Z</updated>
			<id>https://forum.postgresql.org.pl/viewtopic.php?pid=4915#p4915</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Odp: porównanie wartości z dwóch tabel przy użyciu pythona]]></title>
			<link rel="alternate" href="https://forum.postgresql.org.pl/viewtopic.php?pid=4914#p4914"/>
			<content type="html"><![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]]]></content>
			<author>
				<name><![CDATA[depesz]]></name>
				<uri>https://forum.postgresql.org.pl/profile.php?id=1564</uri>
			</author>
			<updated>2013-12-11T09:49:52Z</updated>
			<id>https://forum.postgresql.org.pl/viewtopic.php?pid=4914#p4914</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Odp: porównanie wartości z dwóch tabel przy użyciu pythona]]></title>
			<link rel="alternate" href="https://forum.postgresql.org.pl/viewtopic.php?pid=4908#p4908"/>
			<content type="html"><![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;]]></content>
			<author>
				<name><![CDATA[c_michal]]></name>
				<uri>https://forum.postgresql.org.pl/profile.php?id=627</uri>
			</author>
			<updated>2013-12-10T22:54:36Z</updated>
			<id>https://forum.postgresql.org.pl/viewtopic.php?pid=4908#p4908</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Odp: porównanie wartości z dwóch tabel przy użyciu pythona]]></title>
			<link rel="alternate" href="https://forum.postgresql.org.pl/viewtopic.php?pid=4895#p4895"/>
			<content type="html"><![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]]]></content>
			<author>
				<name><![CDATA[depesz]]></name>
				<uri>https://forum.postgresql.org.pl/profile.php?id=1564</uri>
			</author>
			<updated>2013-12-10T11:05:00Z</updated>
			<id>https://forum.postgresql.org.pl/viewtopic.php?pid=4895#p4895</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Odp: porównanie wartości z dwóch tabel przy użyciu pythona]]></title>
			<link rel="alternate" href="https://forum.postgresql.org.pl/viewtopic.php?pid=4891#p4891"/>
			<content type="html"><![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;]]></content>
			<author>
				<name><![CDATA[c_michal]]></name>
				<uri>https://forum.postgresql.org.pl/profile.php?id=627</uri>
			</author>
			<updated>2013-12-09T21:48:02Z</updated>
			<id>https://forum.postgresql.org.pl/viewtopic.php?pid=4891#p4891</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[porównanie wartości z dwóch tabel przy użyciu pythona]]></title>
			<link rel="alternate" href="https://forum.postgresql.org.pl/viewtopic.php?pid=4880#p4880"/>
			<content type="html"><![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ć?]]></content>
			<author>
				<name><![CDATA[warpath]]></name>
				<uri>https://forum.postgresql.org.pl/profile.php?id=1690</uri>
			</author>
			<updated>2013-12-09T18:04:21Z</updated>
			<id>https://forum.postgresql.org.pl/viewtopic.php?pid=4880#p4880</id>
		</entry>
</feed>
