[FB] Połączenie dwóch selectów bez unii(chyba)

0

Cześć.

Mam 2 niby różne selecty, tzn:

select a as pole1, b as pole2, c as pole3
from
where

select d as pole1, e as pole2, f as pole3
from
where

Różnią się tylko tabelami, z których pobierane są dane. W pierwszym używam innych tabel niż w drugim. Ale zwracają to samo(jak zresztą widać po aliasach).

Teraz mam pytanie, jak je ze sobą połączyć, żeby zwracały mi jeden zbiór danych?
Jak próbuję zrobić unie, to dostaję błąd Invalid command, datatype unknown(zapytanie oddzielnie działają oczywiście)

0

Mamy dwie tabele, które zwracają to samo? Po co 2 tabele z tymi samymi danymi? Napisz coś więcej

0
rafalw napisał(a)

Mamy dwie tabele, które zwracają to samo? Po co 2 tabele z tymi samymi danymi? Napisz coś więcej

To jest tak.
Tabel jest więcej niż 2, załóżmy, że są 4(chociaż faktycznie powiązanych jest więcej).
Pierwsze 2 to klienci i transakcje
Kolejne 2 to dokumenty magazynowe i dostawcy.

I kwestia jest taka, że muszę pokazać jakby historię towaru. Czyli towar został sprzedany(klienci i transakcje), towar został zakupiony(dokumenty magazynowe i dostawcy).

I teraz np. datę operacji otrzymuję z transakcji(sprzedaż), ale też z dokumentów(zakup).
Kontrahenta otrzymuję z powiązania transakcje-klienci(sprzedaż), ale też z powiązania dokumenty-dostawcy(zakup)
W ten deseń.

Próbowałem robić coś z różnymi caseami i inner joinami(z left joinem wyskakiwał błąd kursora :|), żeby umieścić to w jednym zapytaniu, ale nie dało rady, bo w rezultacie otrzymywałem zawsze pusty zbiór.

0

Mamy 2 tabele:

  1. kontrachenci

| id_kontr | nazwa | adres |

  1. tranzakcje

| id_faktury | data_ksieg | data_wpl | kwota | id_kontr | uwagi |

Zapytanie:

SELECT * FROM KONTRACHENCI A, TRANZAKCJE B WHERE A.ID_KONTR = B.ID_KONTR ORDER BY ID_KONTR, DATA

zwróci:

| id_kontr | nazwa | adres | id_faktury | data_ksieg | data_wpl | kwota | uwagi |

chyba ze chodzi ci o zapytanie krzyżowe, ale to w fb inna bajka, trzeba procedurką.

a, i używaj albo odniesień do tabeli albo nazwa przy kolumnach bo czegoś takiego:

SELECT * FROM KONTRACHENCI A, TRANZAKCJE B WHERE A.ID_KONTR = TRANZAKCJE.ID_KONTR

FB 2.0 za cholere nie łyka

0

To nie jest takie proste.
Ogólnie w grę wchodzi 5 tabel:

Jeśli chodzi o sprzedaż:
POS(ID_TRANS, ID_TOW, ILOSC, NETTO, BRUTTO)
TRANSAKCJE(ID, DATA, DOK_TYP)
FAKTURY(ID_TRANS, NUMER)

Jeśli chodzi o zakup:
TOW_DOKMAG(ID_DOKMAG, ID_TOW, ILOSC, NETTO, BRUTTO)
DOKMAG(ID, ID_DOST, DATA, NUMER)

Przedstawiłem tylko kolumny, które odgrywają tu jakąś rolę.
I teraz tak POS przetrzymuje towary(i usługi - rozróżniam to polem smallint: CZY_USL), które zostały sprzedane w transakcji. Transakcja ma datę i typ dokumentu, jaki został wystawiony(faktura, czy paragon) FAKTURY mają numer faktury, a także numer paragonu

Jeśli chodzi o zakup to:
tow_dokmag przechowuje towary, które zostały zakupione i id dokumentu magazynowego, który jest jakby dowodem zakupu. Dokument magazynowy ma datę i program zakłada, że zawsze jest to faktura

Muszę pokazać następujące pola:

Nr paragonu(z FAKTURY lub pusta)
Nr Faktury(z FAKTURY lub DOKMAG)
Typ dokumenu(z TRANSAKCJE lub jeśli sprzedaż to zawsze 'faktura')
OPERACJA('sprzedaż' lub 'kupno')
Ilość(POS lub TOW_DOKMAG)
Data(TRANSAKCJE lub DOKMAG)
Netto, Brutto(POS lub TOW_DOKMAG)
Kontrahent(TRANSAKCJE lub DOKMAG)

Moje niedziałające zapytanie(składnia: UNION) wygląda tak:

select f.numer as nr_fak, f1.numer as nr_par, tr.dok_typ as dok_typ,
       'sprz' as operacja, pos.ilosc as ilosc, tr.data as data,
       (pos.netto_sprz*ilosc) as wart_n, (pos.brutto_sprz*ilosc) as wart_b,
       (case when tr.id_klienta<0 then 'Anonimowy' else
         (case when kl.imie = '' then kl.firma_nazwa else kl.imie || ' ' || kl.nazwisko end) end)
         as kontrahent
from pos
left join transakcje tr on pos.id_trans = tr.id
left join faktury f on f.id_trans = tr.id and f.typ = 'F'
left join faktury f1 on f1.id_trans = tr.id and f.typ = 'P'
left join klienci kl on kl.id = tr.id_klienta
where pos.id_ut = 29

union 

select d.numer as nr_fak, '' as nr_par, 'f' as dok_typ,
       'kupno' as operacja, td.ilosc as ilosc, d.data as data,
       (td.netto_z*ilosc) as wart_n, (td.brutto_z*ilosc) as wart_b,
       dost.nazwa as kontrahent

from tow_dokmag td
left join dokmag d on d.stantyp=1 and td.id_dokmag = d.id
left join dostawcy dost on d.id_dost = dost.id
where td.id_tow = 29

To powinno pokazać tą "historię" dla towaru o id=29.
Z osobna te zapytania działają.
Pierwsze pokazuje historię sprzedaży, drugie zakupu. A chodzi o to, żeby zadziałały razem. Żebym dostał zbiór sprzedaży i zakupu



Moje drugie niedziałające(zawsze zwraca pusty zbiór) zapytanie oparte na case'ach wygląda tak:

select
(case when pos.ilosc is null then d.numer else f.numer end) as nr_fak,
(case when pos.ilosc is null then '' else f1.numer end) as nr_par,
(case when pos.ilosc is null then 'f' else tr.dok_typ end) as dok_typ,
(case when pos.ilosc is null then 'kupono' else 'sprz' end) as operacja,
(case when pos.ilosc is null then td.ilosc else pos.ilosc end) as ilosc,
(case when pos.ilosc is null then d.data else tr.data end) as data,
(case when pos.ilosc is null then (td.netto_ztd.ilosc) else (pos.netto_sprzpos.ilosc) end) as wart_n,
(case when pos.ilosc is null then (td.brutto_ztd.ilosc) else (pos.brutto_sprzpos.ilosc) end) as wart_b,
(case when pos.ilosc is null then dost.nazwa else
(case when tr.id_klienta<0 then 'Anonimowy' else
(case when kl.imie = '' then kl.firma_nazwa else kl.imie || ' ' || kl.nazwisko end) end) end) as kontrahent

from pos, tow_dokmag td
inner join transakcje tr on pos.id_trans = tr.id
inner join faktury f on f.id_trans = tr.id and f.typ = 'F'
inner join faktury f1 on f1.id_trans = tr.id and f.typ = 'P'
inner join klienci kl on kl.id = tr.id_klienta
inner join dokmag d on d.stantyp=1 and td.id_dokmag = d.id
inner join dostawcy dost on d.id_dost = dost.id
where td.id_tow = 29 and pos.id_ut=29 and pos.czy_usl=0


0

1 zapytanie jest ok. ALe STOSOWANIE UNI WYMAGA ABY OBA ZAPYTANIA ZWRACAŁY TE SAME TYPY DANYCH innaczej błąd - Data type unknown. Stosujesz aliasy as coś tam, to nie zmienia typu danych. Musisz zastosować polecenie cast (POLE as TYP_DANYCH), gdy te pola są różne np. Cast(' ' as Char(30)) dla pustego pola o odpowiednim typie char(30) w 2 selekcie:

jestem_stringiem jest tylko w 1 tabelce - typ char(30),

Select id, cos_tam, jestem_stringiem from tabelka
UNION
Select id, cos_tam, Cast(' ' as Char(30)) as jestem_stringiem from tabelka2

i mamy jestem_stringiem w obu zapytaniach i oba są char(30)

Nie wiem czy cast nie jest przypadkiem w UDFach.
Ogólnie to chyba nie za szybkie będzie. Ja bym jednak to zrobił procedurką wybierającą.

0

Ale tam są te same typy danych.
(numery faktur i paragonów są stringami)

0

f1.numer as nr_par

i

'' as nr_par

Jak dla mnie to nie to samo

1 użytkowników online, w tym zalogowanych: 0, gości: 1