Tagi na forum.

Windows 14206 SQL Server 2132
sieci 6796 Windows XP 1921
SQL 6578 Outlook 1838
SBS 3868 Uprawnienia 1777
Windows 2003 2781 IIS 1636
Windows Server 2588 Office 1516
DNS 2315 Skrypt 1499

pokaż wszystkie tagi na forum

kwerend - pomocy !!!

knur1987 2012-02-08 18:49:50
0
avatar
 
 

Witam, jestm nowym użytkownikiem tego forum. Mam pewien problem w pracy z sqlelem. Mianowicie nie wiem jak napisać pewną trudną (przynajmniej dla mnie) kwerendę. Oto wyjściowe nazwy tabel i ich pola (wraz z przykładowymi wartościami):

tabela1
nr_rachunku (np. 0001,00002 itp.)
dni_przeterminowania (np. 0,1,2,3..,100,..., 180, ..250 itp)
saldo (kwota np. 100 PLN itp.)

tabela2
nr_rachunku(jak wyżej)
kod_placówki (np. 1,2,3)

tabela3
kod_placówki (jak wyżej)
region (np. łódź, poznań, gdańsk, warszawa itp.)

Mam napisać kwerendę, której wynikiem była tabelka z następującymi polami:
przedział_dni_przeterminowania(watości: 0,1-30,30-60,..,180+)
poznań
gdańsk
warszawa

a więc tabelka, która pokazywałaby przedziały przeterminownia dla poszczególnych regionów. Wiem, że muszę zjoinować
nr_rachunku z tabeli 1 i 2, a także kod_placówki z tabeli 2i3, ale jak to zrobić ? I co najważniejsze: jaką kwerendę napisać, aby otrzymać taką tabelkę o którą mi chodzi ?

Za wszelką pomoc serdecznie dziękuję i pozdrawiam,

Sorry jeżeli napisałem tego posta w niewłaściwym miejscu. 


tagi: SQL
Liczba postów:

OpenRowset  2012-02-08 23:12:50 #1
1
avatar Ekspert WSS
 
 

Podejrzewam, że masz coś wspólnego z ryzykiem, im prędzej weźmiesz się za R, tym lepiej. Poniżej wulgarny pivot (nie sprawdzałem kodu, ale niej więcej o to chodzi). Myślę, że kolejnym zleceniem będą przeterminowane saldo :)

select region,
  DPD0   = sum(case when dni = 0 then 1.0 else null end)/count(*),
  [DPD1-30]  = sum(case when dni between 1 and 30 then 1.0 else null end)/count(*),
  [DPD31-60]  = sum(case when dni between 31 and 60 then 1.0 else null end)/count(*),
  [DPD61-90]  = sum(case when dni between 61 and 90 then 1.0 else null end)/count(*),
  [DPD91-180] = sum(case when dni between 91 and 180 then 1.0 else null end)/count(*),
  [DPD180+]  = sum(case when dni>180 then 1.0 else null end)/count(*)
from tabela1 as a
  join tabela2 as b on a.nr_rachunku = b.nr_rachunku
  join tabela3 as b on b.kod_placowki = c.kod_placowki
group by region

 


OpenRowset

Cierpliwie zbieram na Windowsa. Jeżeli rozwiązałem problem kliknij [Rozwiązanie], jeżeli pomogłem klinknij [Pomógł mi] :)

knur1987  2012-02-09 08:54:49 #2
0
avatar
 
 

<p>Wczoraj sam na to wpadłem, jednakże dzięki OpenRowset za pomoc :) Tylko wiesz, chodzi o regiony: załóżmy, że mamy 10 regionów, ale 2 z nich mają być pokazane jako suma. Jak to zrobić ? I możesz mi powiedzieć, co ma wspólnego SQL z R ?</p> <p>Pozdrawiam,</p>


OpenRowset  2012-02-09 15:52:38 #2.1
0
avatar Ekspert WSS
 
 

R to pakiet statystyczny/analiza danych, dobrze nadaje się do takich akcji, ma swoje wady ale te są mikro w skali do zalet :)

Co do twojego pytania. Można zrobić to brzydko i można zrobić ładnie. Brzydko:

with ftabela3 as(
select
  Region = case when region in ("Wroclaw", "Warszawa") then "Wroclaw_i_Warszawa" else Region, 
  kod_placowki
from tabela3)

<i tu wstawiasz poprzedniego selscta ale z modyfikacją żeby joinował z ftabela3>

 

Porządnie mógłbyś zrobić tabelę w której zaszyjesz to mapowanie i normalnie jej używał, ale to zależy od tego jak często się to zmienia, w ilu raportach itp.

 

 

 


Edytowano 1 raz. Ostatnio 2012-02-09 15:53:52 przez OpenRowset.

OpenRowset

Cierpliwie zbieram na Windowsa. Jeżeli rozwiązałem problem kliknij [Rozwiązanie], jeżeli pomogłem klinknij [Pomógł mi] :)

knur1987  2012-02-24 22:16:48 #3
0
avatar
 
 

Dzięki RowSet za dotychczasową pomoc :). Niemal codziennie pracuję na postgresie i szybko się uczę, ale jeszcze

wiele mi brakuje by być prawdziwym power-userem. Akurat teraz muszę wyciągnąć dane z pewnych baz danych i mam pewne 2 problemy. Oczywiście mógłbym je obejść kilkoma zapytaniami, ale wolę zrobić to bezpośrednio. Wyobraźmy sobie, że mamy kilka tabel z danymi z różnych miesięcy (mają one te same pola). Zawierają one dane dotyczące np. nr rachunku, regionu, typu produktów itp.

I  teraz chciałbym zapytać o 2 rzeczy:

 

1. boczny union (sam nie wiem jak to lepiej nazwać). Normalny UNION ALL doda mi wiersze z iluś tam zapytań. A jak zrobić to z kolumnami ? Przykładowo mam wynik zapytania z następującymi polami:

nazwa produktu, styczeń_zaang(pokazuje zaangażowanie wg produktów w styczniu). A jak dodać to tego zapytania kolumnę z lutym ? Nie mogę przecież napisać:

Select .... ..... FROM styczeń, luty. Nie mogę też zjoinować stycznia i lutego , bo nie ma jak. Proszę o pomoc.

 

2. a. Piszę sobie zapytanie: 

select

sum ( CASE when .... then  ....  end) / (suma ogółem z kolumny)

FROM ... where warunki

Problem jest z tym (sum ogółem z kolumny), bo tą sumę liczy po uwzglęnieniu tego warunku po where a ja tego nie chce.

2.b czy mogę w miejce tego (suma ogółem z kolumny ) wstawić jakieś zapytanie z select  odwołujące się do innej tabeli ? Co wtedy z FROM ?

 

Jeśli ktoś będzie miał ochotę mi pomóc będę bardzo wdzięczny.

 

Pozdrawiam,

knur. 


OpenRowset  2012-02-25 02:48:21 #3.1
0
avatar Ekspert WSS
 
 

Jeżeli procujesz na postgresie to sprawdz tutaj: http://www.postgresql.org/docs/9.1/static/tablefunc.html. Co prawda nie używałem, ale te f-cje wyglądają atrakcyjnie.

 

ad 1. "Boczny union" to właśnie join, łączysz po nazwie produktu bo przecież dla produktu robisz podsumowanie w wierszu.

ad 2a. Sumę ogółem z kolumny też możesz filtrować case-em, przerzucasz warunek z where. Przykładowo chcesz podać w jednym zapytaniu  średnią (zapomnijmy o avg) wzrostu z ale tylko ludzi do 20 roku życia i średnią płacę kobiet. Mógłbyś oczywiście grupować (doczytaj o groupping sets), ale dla przykładu zrobimy inaczej.

select 
 sum(case when wiek<=20 then wzrost else null end)/sum(case when wiek <= 20 then 1 else 0 end),  
 sum(case when plec='K' then pensja else null end)/sum(case when plec='K' then 1 else 0 end)
from tabela

ad 2a. Pewnie możesz, ale tu robi się niebezpiecznie. Podawaj konkretne przykłady, w ogólności trudno stwierdzić.

 

 

 

 


OpenRowset

Cierpliwie zbieram na Windowsa. Jeżeli rozwiązałem problem kliknij [Rozwiązanie], jeżeli pomogłem klinknij [Pomógł mi] :)

knur1987  2012-02-25 14:00:45 #4
0
avatar
 
 

Dzięki OpenRowset, jednak znów mam pytanie:

ad. 1 boczny union, czyli tak mam 2 tabele styczeń(nr_rachunku, nr_produktu integer, zaangażowanie double) i luty (nr_rachunku, nr_produktu integer, zaangażowanie double) i także funkcję get_product. Żeby wyciągnąć dane o zaangażowaniach po produktach za styczeń i luty w takiej postaci:

 

produkt  styczeń  luty 
     
     
     

 

select
get_product(styczen.nr_produktu),
sum (case when get_product=... then zaangazowanie end),
sum (case when get_product=... then zaangazowanie end)
FROM styczen join luty on styczen.nr_produktu=luty.nr produktu 
ORDER BY get_product(styczen.nr_produktu);

 

O coś takiego chodzi ? 

 

Ad2. Jeżeli napiszę tak:

 

select
sum(case when get_product(styczen_nr.produktu)=... then zaangazowanie end)/sum(styczen.zaangazowanie)
FROM styczen

 

to mi wywali 1, a ja chcę wiedzieć jak to napisać, abym dostał udział danego produktu w całym portfelu banku.

 

Rowset, pomocy :)


OpenRowset  2012-02-25 16:26:11 #5
0
avatar Ekspert WSS
 
 

Proponuję abyś opisał problem, w ostatnim zdaniu są tego zaczątki. Podaj strukturę tabeli, trochę danych przykładowych.Opisuj dokładnie oczekiwane wyjście.

 

Rozmowa zmierza w złym kierunku, ja tu pokazuję pół-triki, jednak tobie brakuje podstaw i od nich powinniśmy zacząć.


OpenRowset

Cierpliwie zbieram na Windowsa. Jeżeli rozwiązałem problem kliknij [Rozwiązanie], jeżeli pomogłem klinknij [Pomógł mi] :)

knur1987  2012-02-25 21:33:22 #6
0
avatar
 
 

Od poczatku mówisz, okej.

Co miesiąc generowane są tabele (styczeń, luty, marzec ...) o tych samych polach. 

Są nimi aktualna_data (np. 2012-01-31), nr_rachunku integer (np. 123456), typ_produktu integer (np. 7062), zaangazowanie_klienta double precision. Oczywiście dla każdego nr_rachunku może być przyporządkowane kilka produktów. 

Jest też funkcja get_product(integer), która dany produkt po numerze przporządkowuje do danej grupy. Np. 7062 i 7100 to karty, 6100, 6072, 6200 to kredyty ratalne, 5500 to inwestycyjne.

Na podstawie comiesięcznych plików chcę zrobić zestawienie, które pokazywało comiesięczny udział poszczególnych produktów w całym porfelu banku. Ostatecznie miałoby to wyglądać tak:

 

produkt  styczeń  luty  marzec 
gotówkowe 45% 40% 42%
obrotowe 10% 15% 12%
ratalne 30% 30% 32%
inwestycyjne 15% 15% 14%
razem 100% 100% 100%

 

Piszę zapytanie tak:

 

select
get_product(styczeń.kod_produktu),
sum(styczeń.zaangazowanie_klienta)/sum(styczeń.zaangazowanie_klienta),
sum(luty.zaangazowanie_klienta)/sum(luty.zaangazowanie_klienta),
sum(marzec.zaangazowanie_klienta)/sum(marzec.zaangazowanie_klienta)
FROM

Nie mam pojęcia czy to ma tak wyglądać i co dać po FROM i jak (lub czy wogóle) powiązać ze sobą miesiące ?

O to mi chodziło. Przyznaję, że mój ostatni post był trochę nieogarnięty. Sorki.


OpenRowset  2012-02-26 00:16:25 #7
0
avatar Ekspert WSS
 
 

Tak jak myślałem, skupiłeś się na tym aby mieć pivota a nie aby to policzyć prawidłowo  właściwe dane. Tu nie trzeba kombinować, grupujesz po produkcie i miesiącu a pivot na końcu, możesz użyć operatora pivot (to forum o ms sql). Jeżeli podasz dane przykładowe i strukturę tabeli w formie skryptu do przeklejenia i uruchomienia to mogę napisać kompletne zapytanie.


Edytowano 1 raz. Ostatnio 2012-02-26 00:17:29 przez OpenRowset.

OpenRowset

Cierpliwie zbieram na Windowsa. Jeżeli rozwiązałem problem kliknij [Rozwiązanie], jeżeli pomogłem klinknij [Pomógł mi] :)

Udziel odpowiedzi

avatar
Treść wpisu:

Zaloguj się lub Zarejestruj się aby wykonać tę czynność.

Idź na górę strony