konto usunięte

Temat: [Oracle-SQL] Na pierwszy rzut oka trywialny problem..

Mam taką sytuację:


Obrazek


Założenie:

Jeżeli pola A1, A2, A3 i A4 mają swoje odzwierciedlenie w polach B1, B2, B3 i B4 (lub odwrotnie) w innym rekordzie (tak jak w tym przypadku) to pokaż tylko jeden z nich.

Pytanie:

Jak napisać takiego select'a? :)Rafał K. edytował(a) ten post dnia 17.03.09 o godzinie 17:37
Łukasz B.

Łukasz B. programista PL/SQL

Temat: [Oracle-SQL] Na pierwszy rzut oka trywialny problem..

Witam,
Testowałem odpowiedź dla:

CREATE TABLE table_name(
A1 Varchar2(32),
A2 Number,
A3 Number,
A4 Number,
B1 Varchar2(32),
B2 Number,
B3 Number,
B4 Number
);

Insert into table_name values('Polska', 1000, 250, 10, 'Francja', 1030, 300, 30);
Insert into table_name values ('Francja', 1030, 300, 30, 'Polska', 1000, 250, 10);

Insert into table_name values ('Włochy', 1030, 300, 30, 'Polska', 1000, 250, 10);
Insert into table_name values ('Polska', 1000, 250, 10, 'Włochy', 1030, 300, 30);

Insert into table_name values ('Niemcy', 1021, 250, 10, 'Rosja', 1045, 300, 30);
Insert into table_name values ('Rosja', 1045, 300, 30, 'Niemcy', 1021, 250, 10);

Select wyświetlający tylko jeden z podwójnych wierszy:

SELECT *
FROM table_name tn
WHERE ROWID IN (SELECT MIN(t1.ROWID)
FROM table_name t1, table_name t2
WHERE (t1.A1=t2.B1 and t1.A2=t2.B2 and t1.A3=t2.B3 and t1.A4=t2.B4)
and ((t1.A1=tn.A1 and t1.A2=tn.A2 and t1.A3=tn.A3 and t1.A4=tn.A4 and t1.B1=tn.B1 and t1.B2=tn.B2 and t1.B3=tn.B3 and t1.B4=tn.B4) or (t1.A1=tn.B1 and t1.A2=tn.B2 and t1.A3=tn.B3 and t1.A4=tn.B4 and t1.B1=tn.A1 and t1.B2=tn.A2 and t1.B3=tn.A3 and t1.B4=tn.A4)));


Nie wyświetla jednak pojedynczych wierszy czyli np:

Insert into table_name values ('Anglia', 1045, 350, 30, 'Hiszpania', 1021, 550, 10);


EDIT:
Natomiast pojedyncze wyświetli prosta modyfikacja powyższego:

SELECT *
FROM table_name tn
WHERE ROWID NOT IN (SELECT t1.ROWID
FROM table_name t1, table_name t2
WHERE (t1.A1=t2.B1 and t1.A2=t2.B2 and t1.A3=t2.B3 and t1.A4=t2.B4)
and ((t1.A1=tn.A1 and t1.A2=tn.A2 and t1.A3=tn.A3 and t1.A4=tn.A4 and t1.B1=tn.B1 and t1.B2=tn.B2 and t1.B3=tn.B3 and t1.B4=tn.B4) or (t1.A1=tn.B1 and t1.A2=tn.B2 and t1.A3=tn.B3 and t1.A4=tn.B4 and t1.B1=tn.A1 and t1.B2=tn.A2 and t1.B3=tn.A3 and t1.B4=tn.A4)));

Złączając oba selecty przy pomocy UNION otrzymamy komplet.Łukasz Bednarek edytował(a) ten post dnia 17.03.09 o godzinie 20:14

konto usunięte

Temat: [Oracle-SQL] Na pierwszy rzut oka trywialny problem..

Pytanie jest teraz, który z nich zostanie wyświetlony?
Łukasz B.

Łukasz B. programista PL/SQL

Temat: [Oracle-SQL] Na pierwszy rzut oka trywialny problem..

Nie jestem do końca pewny czy tak, ale wydaj mi się, że będzie to najstarszy z nich (czyli pierwszy wstawiony).
Rowidy w mojej tabelce przedstawiają się tak:

ROWID
------------------
AAANB8AAEAAAAJnAAA
AAANB8AAEAAAAJnAAB
AAANB8AAEAAAAJnAAC
AAANB8AAEAAAAJnAAD
AAANB8AAEAAAAJnAAE
AAANB8AAEAAAAJnAAF
AAANB8AAEAAAAJnAAG
AAANB8AAEAAAAJnAAH

Po usunięciu pierwszego wiersza i wstawieniu go ponownie mamy:

ROWID
------------------
AAANB8AAEAAAAJnAAB
AAANB8AAEAAAAJnAAC
AAANB8AAEAAAAJnAAD
AAANB8AAEAAAAJnAAE
AAANB8AAEAAAAJnAAF
AAANB8AAEAAAAJnAAG
AAANB8AAEAAAAJnAAH
AAANB8AAEAAAAJnAAI
Łukasz Bednarek edytował(a) ten post dnia 17.03.09 o godzinie 21:36

konto usunięte

Temat: [Oracle-SQL] Na pierwszy rzut oka trywialny problem..

hmm..

dla takiej tabeli:


Obrazek


Twoje zapytanie Łukasz, zwraca wszystkie wiersze lub żadnego (w zależności czy wstawię IN lub NOT IN)

Pola A5 i B5 nie mają znaczenia.

Powinno zwrócić jeden rekord.Rafał K. edytował(a) ten post dnia 18.03.09 o godzinie 11:06
Łukasz B.

Łukasz B. programista PL/SQL

Temat: [Oracle-SQL] Na pierwszy rzut oka trywialny problem..

Tam są dwa różne selecty. Ten wyżej zwraca tylko pojedynczy wiersz z duplikujących się (w selectcie wewnętrznym jest MIN(ROWID)) ten drugi jest zmieniony, żeby zwracał wiersze, które są pojedyncze (nie zachodzi taka sytuacja jak opisałeś). W Twoim przypadku interesuje Cię select, który jest wyżej.

EDIT: Zauważyłem, że tu dodałeś kolumny A5 i B5, których wcześniej nie było. Zaraz zobaczę co jest nie tak;]

EDIT2: Sprawdziłem

Dla tabeli:

CREATE TABLE table_name2(
A1 Varchar2(32),
A2 Number,
A3 Number,
A4 Number,
A5 Number,
B1 Varchar2(32),
B2 Number,
B3 Number,
B4 Number,
B5 Number
);

Insert into table_name2 values('Polska', 1000, 30, 10, 2540,'Francja', 4000, 50, 55, 1210);
Insert into table_name2 values ('Francja', 4000, 50, 55,1210, 'Polska', 1000, 30, 10, 2540);

Insert into table_name2 values('Polska', 1000, 30, 10, 4909,'Francja', 4000, 50, 55, 1976);
Insert into table_name2 values ('Francja', 4000, 50, 55,1976, 'Polska', 1000, 30, 10, 4909);


Zapytanie (zmieniłem tylko table_name na table_name2):

SELECT *
FROM table_name2 tn
WHERE ROWID IN (SELECT MIN(t1.ROWID)
FROM table_name2 t1, table_name2 t2
WHERE (t1.A1=t2.B1 and t1.A2=t2.B2 and t1.A3=t2.B3 and t1.A4=t2.B4)
and ((t1.A1=tn.A1 and t1.A2=tn.A2 and t1.A3=tn.A3 and t1.A4=tn.A4 and t1.B1=tn.B1 and t1.B2=tn.B2 and t1.B3=tn.B3 and t1.B4=tn.B4) or (t1.A1=tn.B1 and t1.A2=tn.B2 and t1.A3=tn.B3 and t1.A4=tn.B4 and t1.B1=tn.A1 and t1.B2=tn.A2 and t1.B3=tn.A3 and t1.B4=tn.A4)));


Zwraca tylko pierwszy z wstawionych wierszy, czyli ten:

Insert into table_name2 values('Polska', 1000, 30, 10, 2540,'Francja', 4000, 50, 55, 1210);
Łukasz Bednarek edytował(a) ten post dnia 18.03.09 o godzinie 11:31

konto usunięte

Temat: [Oracle-SQL] Na pierwszy rzut oka trywialny problem..

Tak, faktycznie. O to mi chodziło.

Zapytanie teraz zwraca 1 rekord tak jak zakładano.
Swoją drogą ciekawy pomysł z tym ROWID.

Dzięki wielkie za pomoc! :)
Igor Piotr I.

Igor Piotr I. IT manager/Senior
Oracle Developer

Temat: [Oracle-SQL] Na pierwszy rzut oka trywialny problem..

yyy a tak:

select a1 x1,a2 x2,a3 x3,a4 x4 from table
union
select b1 x1,b2 x2,b3 x2,b4 x4 from table
Łukasz B.

Łukasz B. programista PL/SQL

Temat: [Oracle-SQL] Na pierwszy rzut oka trywialny problem..

Igor Piotr I.:
yyy a tak:

select a1 x1,a2 x2,a3 x3,a4 x4 from table
union
select b1 x1,b2 x2,b3 x2,b4 x4 from table

Też o tym myślałem, ale w momencie, gdy potrzebny jest cały wiersz to chyba nie przejdzie. Rozszerzając go do postaci:

select a1 x1,a2 x2,a3 x3,a4 x4, b1 x5,b2 x6,b3 x7,b4 x8 from table_name
union
select b1 x1,b2 x2,b3 x2,b4 x4, a1 x5,a2 x6,a3 x7,a4 x8 from table_name;

będą duplikaty.
To chyba zależy od danych. Gdy np wiersz przechowuje statystyki jakiegoś meczu, to takie rozdzielenie wiersza do niczego dobrego nie prowadzi.

konto usunięte

Temat: [Oracle-SQL] Na pierwszy rzut oka trywialny problem..

Tak, chodziło mi o to aby dane były pokazywane w jednym wierszu,

a1, a2, a3, a4, b1, b2, b3, b4

unikatowo /wg założeń/Rafał K. edytował(a) ten post dnia 18.03.09 o godzinie 16:10

konto usunięte

Temat: [Oracle-SQL] Na pierwszy rzut oka trywialny problem..

Igor Piotr I.:
yyy a tak:

select a1 x1,a2 x2,a3 x3,a4 x4 from table
union
select b1 x1,b2 x2,b3 x2,b4 x4 from table
Rafał K.:
Tak, chodziło mi o to aby dane były pokazywane w jednym wierszu,

a1, a2, a3, a4, b1, b2, b3, b4

unikatowo /wg założeń/Rafał K. edytował(a) ten post dnia 18.03.09 o godzinie 16:10

a tak?:

select a1 x1,a2 x2,a3 x3,a4 x4,b1 x5,b2 x6,b3 x7,b4 x8 from table
union
select b1 x1,b2 x2,b3 x2,b4 x4,a1 x5,a2 x6,a3 x7,a4 x8 from table
Wojciech Młodzianowski edytował(a) ten post dnia 19.03.09 o godzinie 09:57

konto usunięte

Temat: [Oracle-SQL] Na pierwszy rzut oka trywialny problem..

w sumie Lukasz juz o tym pisal, czemu to niby nie mialoby zadzialas?
union da unikatowe wiersze nie?
Igor Piotr I.

Igor Piotr I. IT manager/Senior
Oracle Developer

Temat: [Oracle-SQL] Na pierwszy rzut oka trywialny problem..

Faktycznie problem prosty tylko z pozoru.
Łukasz B.

Łukasz B. programista PL/SQL

Temat: [Oracle-SQL] Na pierwszy rzut oka trywialny problem..

Tak Wojtku, UNION da unikatowe, ale zauważ, że jak masz:

Polska 1000 30 10 2540 Francja 4000 50 55 1210
Francja 4000 50 55 1210 Polska 1000 30 10 2540

i zrobisz tak jak mówisz to masz:

Polska 1000 30 10 2540 Francja 4000 50 55 1210
Francja 4000 50 55 1210 Polska 1000 30 10 2540
UNION
Francja 4000 50 55 1210 Polska 1000 30 10 2540
Polska 1000 30 10 2540 Francja 4000 50 55 1210

czyli da oba.Łukasz Bednarek edytował(a) ten post dnia 19.03.09 o godzinie 13:08
Karol Wojtiuk

Karol Wojtiuk Team Leader, SMT
Software

Temat: [Oracle-SQL] Na pierwszy rzut oka trywialny problem..

no to może brute force:) :

Select Distinct case a1>b1 then a1 else b1 end a1, case a1>b1 then a2 else b2 end a2, case a1>b1 then a3 else b3 end a3, case
a1>b1 then a4 else b4 end a4, case a1>b1 then b1 else a1 end b1, case a1>b1 then b2 else a2 end b2, case a1>b1 then b3 else a3 end b3, casea1>b1 then b4 else a4 end b4 from table

Może być?Karol Wojtiuk edytował(a) ten post dnia 26.03.09 o godzinie 20:16

Temat: [Oracle-SQL] Na pierwszy rzut oka trywialny problem..

Karol Wojtiuk:
no to może brute force:) :

Select Distinct case a1>b1 then a1 else b1 end a1, case a1>b1 then a2 else b2 end a2, case a1>b1 then a3 else b3 end a3, case
a1>b1 then a4 else b4 end a4, case a1>b1 then b1 else a1 end b1, case a1>b1 then b2 else a2 end b2, case a1>b1 then b3 else a3 end b3, casea1>b1 then b4 else a4 end b4 from table

Może być?


Ale to chyba bardziej Postgres niż Oracle ;)
Hmm, mój błąd, rzeczywiście w Oraclu też można wstawić tą konstrukcję w zapytaniu, nigdy się z czymś takim nie spotkałem :)Łukasz Gałązka edytował(a) ten post dnia 27.03.09 o godzinie 09:27

konto usunięte

Temat: [Oracle-SQL] Na pierwszy rzut oka trywialny problem..

a tak wogole to chyba lepiej by bylo przeprojektowac tabele/wstawianie zeby usunac nadmiarowe dane ;)
Przemysław Kantyka

Przemysław Kantyka Oracle Certified
Professional, Oracle
Database SQL
Certif...

Temat: [Oracle-SQL] Na pierwszy rzut oka trywialny problem..

Wojciech Młodzianowski:
a tak wogole to chyba lepiej by bylo przeprojektowac tabele/wstawianie zeby usunac nadmiarowe dane ;)

Dokładnie

Problem jest złożony bo nie zachowano w trakcie tworzenia tabel reguł normalizacji.

Pomysł z ROWID od razu budzi moją niechęć chociaż działa - tzn. lepiej trzymać się zasady że każda tabela ma klucz główny zdefiniowany przez nas - bo póki co tego nie masz.

Jeśli upierasz się przy takim układzie tabel - jednym z rozwiązań są też funkcje analityczne ROWNUM i COUNT i świta mi po głowie podzapytanie.

PozdrawiamPrzemysław Kantyka edytował(a) ten post dnia 10.04.09 o godzinie 12:07
Piotr B.

Piotr B.
http://www.linkedin.
com/in/piotrbystrzyc
ki

Temat: [Oracle-SQL] Na pierwszy rzut oka trywialny problem..

Czesc,
Napisalem w biegu, nie sprawdzalem, nie testowalem, moze bedzie OK:

select
from table t1
where exists
(select from table t2
where t1.A1 = t2.B1 and t1.A2 = t2.B2 and t1.a3 = t2.b3 and t1.A4 = t2.b4 and t1.a1 < t2.b1)

PBY



Wyślij zaproszenie do