2014-10-01 19 views
9

Mam dwie tabele:konwersji wielu wierszy do kolumn w MySQL

TABLEA

+-------+--------+ 
| Data | Acc_No | 
+-------+--------+ 
| Unix |  10 | 
| Linux |  20 | 
+-------+--------+ 

TableB

+-----+----------+--------+ 
| Obj | Type  | Amount | 
+-----+----------+--------+ 
| 10 | rev  | 100.00 | 
| 10 | revision | 200.00 | 
+-----+----------+--------+ 

Chcę wyjście jak ten

+-------+--------+----------+--------+-----------+----------+ 
| Data | Acc_No | Type  | Amount | Type_1 | Amount_1 | 
+-------+--------+----------+--------+-----------+----------+ 
| Unix | 10  | rev  | 100 | revision | 200  | 
+-------+--------+----------+--------+-----------+----------+ 

Próbowałem to zrobić za pomocą prostego sprzężenia. Oto zapytanie:

SELECT a.Data,a.Acc_No, b.Type, b.Amount, bb.Type AS "Type_1", bb.Amount AS "Amount_1" 
FROM TableA a,TableB b, TableB bb 
WHERE a.Acc_No = b.Obj AND 
     b.Obj = bb.Obj AND 
     bb.Obj = a.Acc_No AND 
     a.Acc_No =10; 

Ale mam to wyjście.

+------+--------+----------+--------+----------+----------+ 
| Data | Acc_No | Type  | Amount | Type_1 | Amount_1 | 
+------+--------+----------+--------+----------+----------+ 
| Unix |  10 | rev  | 100.00 | rev  | 100.00 | 
| Unix |  10 | revision | 200.00 | rev  | 100.00 | 
| Unix |  10 | rev  | 100.00 | revision | 200.00 | 
| Unix |  10 | revision | 200.00 | revision | 200.00 | 
+------+--------+----------+--------+----------+----------+ 

Próbowałem wyszukać odpowiedź na tej stronie, a ja nawet googlowałem, ale nie znalazłem na to właściwej odpowiedzi.

+0

Woli dwa typy zawsze są "rev" i "rewizja"? Czy będą inne typy? Czy będzie więcej niż dwa typy? – JNevill

+0

Nie, istnieją tylko dwa typy, rev i rewizja. To tylko przykładowe dane, ale moje wyższe oczekiwania oczekują tego rodzaju wyników. – Am1t

Odpowiedz

5

Twoje obecne zapytanie jest blisko, ale proponuję wprowadzić kilka drobnych zmian, aby uzyskać wynik. Jeśli chcesz "przestawić" dane za pomocą JOIN, musisz rozróżnić, którą wartość chcesz zwrócić z TableB w każdym następnym sprzężeniu.

Na przykład, gdy chcesz zwrócić type=rev, musisz uwzględnić określony filtr dla tej wartości. Wtedy zrobisz to samo z type=revision. Sugerowałbym także użycie LEFT JOIN, aby dołączyć do TableB, jeśli nie masz wartości type dla każdego, a następnie nadal będziesz zwracał dane.

select 
    a.data, 
    a.acc_no, 
    b.type, 
    b.amount, 
    bb.type as type_1, 
    bb.amount as amount_1 
from tablea a 
left join tableb b 
    on a.acc_no = b.obj 
    and b.type = 'rev' 
left join tableb bb 
    on a.acc_no = bb.obj 
    and bb.type = 'revision'; 

Zobacz SQL Fiddle with Demo

Można też uzyskać ten wynik za pomocą niektórych agregację warunkowego, wtedy nie trzeba dołączyć do TableB wiele razy:

select 
    a.data, 
    a.acc_no, 
    max(case when b.type = 'rev' then b.type end) as type, 
    max(case when b.type = 'rev' then b.Amount end) as Amount, 
    max(case when b.type = 'revision' then b.type end) as type_1, 
    max(case when b.type = 'revision' then b.Amount end) as Amount_1 
from tablea a 
left join tableb b 
    on a.acc_no = b.obj 
group by a.data, a.acc_no 
order by a.acc_no; 

Zobacz SQL Fiddle with Demo

+0

Bardzo dziękuję za wysiłek, ale chcę uzyskać dokładny wynik, jak pokazałem w oczekiwanym wyniku. Czy myślisz, że tworzenie widoku i wyświetlanie jego zawartości będzie działać? – Am1t

+0

@ Am1t Co masz na myśli, że chcesz uzyskać dokładny wynik, który pokazałeś? Daje to dokładny wynik, ale nie filtrowałem dla 'acc_no = 10'. Jeśli chodzi o twoje drugie pytanie, możesz umieścić je w widoku. – Taryn

+0

Chcę tylko tych danych, które są związane z "Acc_No = 10", ale po wykonaniu powyższego zapytania otrzymuję Linux, który ma "Acc_No = 20". Dlatego filtrowanie powinno odbywać się w oparciu o "Acc_No = 10". – Am1t

Powiązane problemy