Jak posortować tabelę

0

Witajcie mam tabelę w oracle gdzie mam takie kolumny:

PK REC_ID COL_A COLB COL_C
1 abc null 9 1
2 def hij null 2
3 ggg null null 1
4 abc null null 2
5 opr null null 1

i teraz potrzebuję tak zrobić ordera aby dane wróciły mi tak

PK REC_ID COL_A COLB COL_C
1 abc null 9 1
4 abc null null 2
3 ggg null null 1
5 opr null null 1
2 def hij null 2

Chodzi o to, że najpierw pobieram te same REC_ID potem sprawdzam czy COL_A jest null jak jest to sprawdzam COL_B nie jest null to następne mają być rekordy z tym samym COL_B potem sprawdzam COL_C jak nie są null to pobieram wszystkie rekordy z tym smaym COL_C itd

Pomożecie bo ja wymiękłem 😛 (ach ten biznes) 😄

1

Cztery selekty złączone union all? i tam w were wpisać kombinacje is null, is not null?

Bo chyba jest flaga mówiąca czy nule mają być sprzodu czy z tyłu, ale chyba nie można jej ustawiać per kolumna

ORDER BY { column-Name | ColumnPosition | Expression }
    [ ASC | DESC ]
    [ NULLS FIRST | NULLS LAST ]
    [ , column-Name | ColumnPosition | Expression 
    [ ASC | DESC ]
    [ NULLS FIRST | NULLS LAST ]
    ] * 

A może można per columna?
https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqlj13658.html

0

Nie do końca rozumiem co mi to da?

1
woolfik napisał(a):

Witajcie mam tabelę w oracle gdzie mam takie kolumny:
Chodzi o to, że najpierw pobieram te same REC_ID potem sprawdzam czy COL_A jest null jak jest to sprawdzam COL_B nie jest null to następne mają być rekordy z tym samym COL_B potem sprawdzam COL_C jak nie są null to pobieram wszystkie rekordy z tym smaym COL_C itd

Pomożecie bo ja wymiękłem 😛 (ach ten biznes) 😄

Co to znaczy "sprawdzam, czy jest null" i "wyświetlam z tym samym COL_B"?
Co jeśli COL_A nie jest null? Co jeśli COL_B są różne? Napisz to bardziej po polsku.
Ja to rozumiem (a właściwie się domyślam) tak, że chcesz posortować po REC_ID, COL_A, COL_B, COL_C przy założeniu, że nulle mają występować na końcu.

Działam na MS SQLu, więc nie mam takich wodotrysków, jak Oraclowcy i mógłbym zrobić to w taki brzydki sposób:

ORDER BY REC_ID ASC
  , ISNULL(COL_A,CHAR(254)) ASC
  , ISNULL(COL_B,CHAR(254)) ASC
  , ISNULL(COL_C,CHAR(254)) ASC

Natomiast internety mówią, że w bardziej cywilizowanych bazach (w tym Oracle) może zadziałać:

ORDER BY REC_ID ASC
  , COL_A NULLS LAST
  , COL_B NULLS LAST
  , COL_C NULLS LAST
2
ORDER BY
  REC_ID ASC,
  COL_A ASC NULLS LAST,
  COL_B ASC NULLS LAST
0

Może inaczej ... biorę rekord PK=1 sprawdzam czy COL_A jest pusta jak NIE to szukam wszystkich rekordów z tą wartością COL_A, potem to samo dla B i C
Przechodzę do PK=2 i robię to samo ale jak PK = 2 wpadło już w tym wżej bo np COL_C jest taka sama dla PK=1 i PK2 to idę do PK=3 itd ...

1
woolfik napisał(a):

Może inaczej ... biorę rekord PK=1 sprawdzam czy COL_A jest pusta jak NIE to szukam wszystkich rekordów z tą wartością COL_A, potem to samo dla B i C
Przechodzę do PK=2 i robię to samo ale jak PK = 2 wpadło już w tym wżej bo np COL_C jest taka sama dla PK=1 i PK2 to idę do PK=3 itd ...

Czyli potrzebujesz odwrócić sortowanie.

ORDER BY 
    COL_A NULLS LAST
  , COL_B NULLS LAST
  , COL_C NULLS LAST
  , REC_ID

A jak to nie to, to zrób jakiś db fiddle z większą liczbą różnorodnych rekordów, żeby było na czym psuć :)

Ale coś mi się wydaje, że albo masz jakiś nienaturalny problem biznesowy, albo to XY.

Bo jak się tak zastanawiam nad tym, co naskrobałeś, to wychodzi mi, że PK=1 zawsze ma być pierwszy (bez względu na wszystko), a reszta rekordów będzie zmieniać kolejność w pięknym tańcu "sortowania", a zmiana COL_A jednego z rekordów może niemal całkowicie przetasować listę zwracanych rekordów...

2

Nie podałeś nazwy tabeli, to sobie ją wymyśliłem.
Nie napisałeś też, jakie ma być sortowanie na każdym z kroków (jeżeli 10 rekordów będzie miało takie samo REC_ID, to w jakiej kolejności je wrzucić), więc dodałem brzydkie sortowanie.
Nie siliłem się na piękne aliasy, skoro nazwy kolumn tez piękne nie są 🙃

Całość nie jest optymalna (tak jak nieoptymalna jest struktura danych dla zadanego problemu), ale działa dla podanego zestawu danych (działa na MS SQL, ale powinno działać na każdym silniku.

select pk, REC_id, col_a, col_b, col_c 
from (
	select x.*
		,pd.pk as ppk
		,case 
			when x.REC_id = pd.REC_id then '1'+CONVERT(varchar,x.REC_id)
			when x.col_a = pd.col_a then '2'+CONVERT(varchar,x.col_a)
			when x.col_b = pd.col_b then '3'+CONVERT(varchar,x.col_b)
			when x.col_c = pd.col_c then '4'+CONVERT(varchar,x.col_c)
		end as sort
	from xyz x
	outer apply (
		select MIN(pk) par_pk 
		from xyz as x2 
		where x2.rec_id = x.rec_id
			or x2.col_a = x.col_a
			or x2.col_b = x.col_b
			or x2.col_c = x.col_c
	) as p
	left join xyz pd ON pd.pk = p.par_pk
) ts
order by ppk,sort

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