[MSSQL] ORDER BY - "NULL" na końcu

0

Mam skrypt w MSSQL wyciągający 3 rozmiary asortymentu (nie wszystkie wartości są podane - więc czasem wskakuje wartość NULL (akurat u mnie BRAK WYMIARU ale jeżeli to przeszkadza mogę to skasować) - kolumny tworzę tak:

'Grubość' = isnull((select ltrim(rtrim(replace (ca.Nazwa,'T:',''))) from ModelDanychContainer.CechyAsortymentuAsortyment caa join ModelDanychContainer.CechyAsortymentu ca on ca.Id = caa.Cechy_Id WHERE caa.Asortymenty_Id = ModelDanychContainer.Asortymenty.Id AND ca.Nazwa LIKE 'A:%'), 'BRAK WYMIARU')

Przy poniższym sortowaniu (również bez użycia isnull()) puste wartości pokazują się najpierw, a chciałbym żeby pokazywały się na końcu.

ORDER BY Grubość,Szerokość,Wysokość

Co prawda znalazłem sobie parę potencjalnych rozwiązań, lecz przywołując kolumnę jako grubość otrzymuję błąd 207 INVALID COLUMN NAME 'GRUBOŚĆ'.

Więc mam 2 pytania:

  • Jak przesortować w MSSQL coś na zasadzie NULLS LAST z Oracle

  • Jak w funkcjach odwołać się do stworzonych tabel z nadaną nazwą własną

0
haxer napisał(a):
  • Jak przesortować w MSSQL coś na zasadzie NULLS LAST z Oracle

zeby posortowac po kolumna z nullami na koncu:

order by isnull(kolumna), kolumna
  • Jak w funkcjach odwołać się do stworzonych tabel z nadaną nazwą własną

niestety nie rozumiem pytania, jakis przyklad co bys chcial wlasciwie zrobic?

0

Czyli muszę zrobić tak? (rozwiązanie wydaję się trochę niepotrzebnie obciążające bazę)

ORDER BY isnull((select ltrim(rtrim(replace (ca.Nazwa,'T:',''))) from ModelDanychContainer.CechyAsortymentuAsortyment caa join ModelDanychContainer.CechyAsortymentu ca on ca.Id = caa.Cechy_Id WHERE caa.Asortymenty_Id = ModelDanychContainer.Asortymenty.Id AND ca.Nazwa LIKE 'A:%'))

Jeśli robię:

isnull(Grubość)

to otrzymuję błąd 207 INVALID COLUMN NAME 'GRUBOŚĆ' - właśnie tego dotyczyło drugie pytanie

Dodatkowo pokazuje mi, że dla isnull trzeba podać 2 argumenty, lecz mimo podania 2 argumentu jako: 999999 sortowanie się nie zmienia. cały kod wygląda tak:

SELECT
   Asortymenty.Id
  ,Asortymenty.Symbol
  ,Asortymenty.Nazwa
  ,'Grubość' = isnull((select ltrim(rtrim(replace (ca.Nazwa,'A:',''))) from ModelDanychContainer.CechyAsortymentuAsortyment caa join ModelDanychContainer.CechyAsortymentu ca on ca.Id = caa.Cechy_Id WHERE caa.Asortymenty_Id = ModelDanychContainer.Asortymenty.Id AND ca.Nazwa LIKE 'A:%'),'BRAK WYMIARU')
  ,'Szerokość' = isnull((select ltrim(rtrim(replace (ca.Nazwa,'B:',''))) from ModelDanychContainer.CechyAsortymentuAsortyment caa join ModelDanychContainer.CechyAsortymentu ca on ca.Id = caa.Cechy_Id WHERE caa.Asortymenty_Id = ModelDanychContainer.Asortymenty.Id AND ca.Nazwa LIKE 'B:%'), 'BRAK WYMIARU')
  ,'Wysokość' = isnull((select ltrim(rtrim(replace (ca.Nazwa,'C:',''))) from ModelDanychContainer.CechyAsortymentuAsortyment caa join ModelDanychContainer.CechyAsortymentu ca on ca.Id = caa.Cechy_Id WHERE caa.Asortymenty_Id = ModelDanychContainer.Asortymenty.Id AND ca.Nazwa LIKE 'C:%'), 'BRAK WYMIARU')
  ,'Stan' = Sum(StanyMagazynowe.IloscDostepna)
FROM ModelDanychContainer.Asortymenty 
FULL OUTER JOIN ModelDanychContainer.GrupyAsortymentu ON Asortymenty.Grupa_Id=GrupyAsortymentu.ID
INNER JOIN ModelDanychContainer.StanyMagazynowe ON StanyMagazynowe.Asortyment_ID=Asortymenty.ID
WHERE ModelDanychContainer.GrupyAsortymentu.Nazwa Like 'Alternatory'
AND Asortymenty.IsInRecycleBin Like 0
GROUP BY Asortymenty.ID,Asortymenty.Symbol,Asortymenty.Nazwa
ORDER BY 
   isnull((select ltrim(rtrim(replace (ca.Nazwa,'T:',''))) from ModelDanychContainer.CechyAsortymentuAsortyment caa join ModelDanychContainer.CechyAsortymentu ca on ca.Id = caa.Cechy_Id WHERE caa.Asortymenty_Id = ModelDanychContainer.Asortymenty.Id AND ca.Nazwa LIKE 'A:%'),999999999999999999999)
  ,isnull((select ltrim(rtrim(replace (ca.Nazwa,'W:',''))) from ModelDanychContainer.CechyAsortymentuAsortyment caa join ModelDanychContainer.CechyAsortymentu ca on ca.Id = caa.Cechy_Id WHERE caa.Asortymenty_Id = ModelDanychContainer.Asortymenty.Id AND ca.Nazwa LIKE 'B:%'),999999999999999999999)
  ,isnull((select ltrim(rtrim(replace (ca.Nazwa,'H:',''))) from ModelDanychContainer.CechyAsortymentuAsortyment caa join ModelDanychContainer.CechyAsortymentu ca on ca.Id = caa.Cechy_Id WHERE caa.Asortymenty_Id = ModelDanychContainer.Asortymenty.Id AND ca.Nazwa LIKE 'C:%'),999999999999999999999)

Kod ten tak samo działa dla mojej pierwotnej wersji z

ORDER BY Grubość,Szerokość,Wysokość
0

Nie używaj PLiterek w nazwach obiektów BD - prosisz się o problemy.
Poza tym aliasy (wg ANSI) definiuje się:

wyrazenie [AS] Alias

i na pewno ten Alias nie jest w apostrofach.
Szczerze mówiąc, to nie wiem, czy on ci teraz nie robi porównania strinu 'Grubość' do wyniku ifnull() :)

W końcu zawsze możesz zrobić ORDER BY 4,5,6

0

Błąd poleg na tym, że wstawiasz dla nulla 9999999, a jakby nie patrząc (wykonujesz niejawną konwersję) to liczby zawsze będą przed znakami podczas sortowania rosnąco...

Dodatkowo zastanów się jak nie czytelne piszesz zapytania i nieoptymalne, dla każdego zwracanego wiersza baza wykonuje dodatkow 3 podzapytania...

Można to poprawić tak:

SELECT
   Asortymenty.Id
  ,Asortymenty.Symbol
  ,Asortymenty.Nazwa
  ,Isnull(Grubość,'BRAK WYMIARU') as Grubość
  ,Isnull(Szerokość,'BRAK WYMIARU') as Szerokość
  ,Isnull(Wysokość,'BRAK WYMIARU') as Wysokość
  ,'Stan' = SUM(StanyMagazynowe.IloscDostepna)
FROM 
	ModelDanychContainer.Asortymenty 
	FULL OUTER JOIN ModelDanychContainer.GrupyAsortymentu ON Asortymenty.Grupa_Id=GrupyAsortymentu.ID
	INNER JOIN ModelDanychContainer.StanyMagazynowe ON StanyMagazynowe.Asortyment_ID=Asortymenty.ID
	LEFT JOIN (SELECT 
				ltrim(rtrim(REPLACE (ca.Nazwa,'T:',''))) as Grubość
				,caa.Asortymenty_Id as aID
			FROM 
				ModelDanychContainer.CechyAsortymentuAsortyment caa 
				JOIN ModelDanychContainer.CechyAsortymentu ca ON ca.Id = caa.Cechy_Id 
				
			WHERE 
				ca.Nazwa LIKE 'A:%') G on g.aID = ModelDanychContainer.Asortymenty.Id
	LEFT JOIN (SELECT 
				ltrim(rtrim(REPLACE (ca.Nazwa,'W:',''))) as Szerokość
				,caa.Asortymenty_Id as aID
			FROM 
				ModelDanychContainer.CechyAsortymentuAsortyment caa 
				JOIN ModelDanychContainer.CechyAsortymentu ca ON ca.Id = caa.Cechy_Id 
				
			WHERE 
				ca.Nazwa LIKE 'B:%') s on s.aID = ModelDanychContainer.Asortymenty.Id
	LEFT JOIN (SELECT 
				ltrim(rtrim(REPLACE (ca.Nazwa,'C:',''))) as Wysokość
				,caa.Asortymenty_Id as aID
			FROM 
				ModelDanychContainer.CechyAsortymentuAsortyment caa 
				JOIN ModelDanychContainer.CechyAsortymentu ca ON ca.Id = caa.Cechy_Id 				
			WHERE 
				ca.Nazwa LIKE 'C:%') W on W.aID = ModelDanychContainer.Asortymenty.Id
WHERE 
	ModelDanychContainer.GrupyAsortymentu.Nazwa LIKE 'Alternatory'
	AND Asortymenty.IsInRecycleBin LIKE 0
GROUP BY 
	Asortymenty.ID
	,Asortymenty.Symbol
	,Asortymenty.Nazwa
	,Grubość
    ,Szerokość
    ,Wysokość
ORDER BY 
     case when grubość is null then 1 else 0 end
	 ,Grubość
     ,case when szerokość is null then 1 else 0 end
	 ,szerokość
     ,case when wysokość is null then 1 else 0 end
	 ,Wysokość
1

z jakis powodow zalozylam ze to mysql ;)
nie mam za bardzo jak sprawdzic ale takie cos powinno dzialac:

SELECT
   Asortymenty.Id
  ,Asortymenty.Symbol
  ,Asortymenty.Nazwa
  ,isnull((SELECT ltrim(rtrim(REPLACE (ca.Nazwa,'A:',''))) FROM ModelDanychContainer.CechyAsortymentuAsortyment caa JOIN ModelDanychContainer.CechyAsortymentu ca ON ca.Id = caa.Cechy_Id WHERE caa.Asortymenty_Id = ModelDanychContainer.Asortymenty.Id AND ca.Nazwa LIKE 'A:%'),'BRAK WYMIARU') grubosc
  ,isnull((SELECT ltrim(rtrim(REPLACE (ca.Nazwa,'B:',''))) FROM ModelDanychContainer.CechyAsortymentuAsortyment caa JOIN ModelDanychContainer.CechyAsortymentu ca ON ca.Id = caa.Cechy_Id WHERE caa.Asortymenty_Id = ModelDanychContainer.Asortymenty.Id AND ca.Nazwa LIKE 'B:%'), 'BRAK WYMIARU') szerokosc
  ,isnull((SELECT ltrim(rtrim(REPLACE (ca.Nazwa,'C:',''))) FROM ModelDanychContainer.CechyAsortymentuAsortyment caa JOIN ModelDanychContainer.CechyAsortymentu ca ON ca.Id = caa.Cechy_Id WHERE caa.Asortymenty_Id = ModelDanychContainer.Asortymenty.Id AND ca.Nazwa LIKE 'C:%'), 'BRAK WYMIARU') wysokosc
  ,SUM(StanyMagazynowe.IloscDostepna) stan
FROM ModelDanychContainer.Asortymenty 
FULL OUTER JOIN ModelDanychContainer.GrupyAsortymentu ON Asortymenty.Grupa_Id=GrupyAsortymentu.ID
INNER JOIN ModelDanychContainer.StanyMagazynowe ON StanyMagazynowe.Asortyment_ID=Asortymenty.ID
WHERE ModelDanychContainer.GrupyAsortymentu.Nazwa LIKE 'Alternatory'
AND Asortymenty.IsInRecycleBin LIKE 0
GROUP BY Asortymenty.ID,Asortymenty.Symbol,Asortymenty.Nazwa
ORDER BY grubosc, wysokosc, szerokosc
0

@katelx: Dzięki wielkie działa tak jak powinno :)

@Panczo: Owszem masz rację, niestety szczerze powiem, że bardzo słabo się na tym znam, na razie niezbyt szczególnie się edukuję w tym kierunku, tylko tyle co by w firmie ułatwić pracownikom pracę.
Dzięki wielkie również za wskazówki, przeanalizuję sobie kod, jednak aktualnie coś w nim nie gra, gdyż zwraca w mojej bazie 87761 wyników zamiast 587, które powinien zwrócić - te same rekordy są zwracane po około 168 razy.
Prawidłowy wynik: https://pastebin.com/Cp1P370A
Wynik z błędem - częściowy - pastebin nie pozwala wstawić zbyt dużo(top 1300): https://pastebin.com/2DXUVua7
Kolumny grubosc i szerokosc się zgadzają, jednak problem widzę, że jest w kolumnach wysokosc i stan

1

Mój błąd z joinem wysokości, jest:

    LEFT JOIN (SELECT 
                ltrim(rtrim(REPLACE (ca.Nazwa,'C:',''))) AS Wysokość
                ,caa.Asortymenty_Id AS aID
            FROM 
                ModelDanychContainer.CechyAsortymentuAsortyment caa 
                JOIN ModelDanychContainer.CechyAsortymentu ca ON ca.Id = caa.Cechy_Id               
            WHERE 
                ca.Nazwa LIKE 'C:%') W ON g.aID = ModelDanychContainer.Asortymenty.Id

Powinno być:

    LEFT JOIN (SELECT 
                ltrim(rtrim(REPLACE (ca.Nazwa,'C:',''))) AS Wysokość
                ,caa.Asortymenty_Id AS aID
            FROM 
                ModelDanychContainer.CechyAsortymentuAsortyment caa 
                JOIN ModelDanychContainer.CechyAsortymentu ca ON ca.Id = caa.Cechy_Id               
            WHERE 
                ca.Nazwa LIKE 'C:%') W ON w.aID = ModelDanychContainer.Asortymenty.Id

zwróć uwagę na warunek sprzężenia, było g.aID a powinno być w.aID

Poprawiłem w poście.

0

@Panczo: Zgadza się, teraz wszystko jest ok.

Korzystając jeszcze z tematu mam problem z połączeniem tych 3 kolumn (Grubość wysokość szerokość) - gdy zrobię:

Grubość + ' x ' + Szerokość + ' x ' + Wysokość

To wszystko jest ok, chyba że jedna z wartości nie jest podana (BRAK WARTOŚCI) wtedy mam puste pole, a chciałbym żeby było 0. (Np. 19 x 0 x 22)
Próbowałem różnymi funkcjami: IF, CASE ale napotykałem różne błędy (między innymi z typem danych) z którymi niezbyt mogłem sobie poradzić.

1

No to najprościej to chyba tak:

isnull(Grubość,'0') + ' x ' + isnull(Szerokość,'0') + ' x ' + isnull(Wysokość,'0')
0

@Panczo: No tak, zbyt proste bym na to wpadł ;) Dzięki!

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