ORA-00936: missing expression in order by case - sql

Hello i have problem with missing expression in this code:
create or replace view tabulkaliga as
select t.nazov, zs.zapasov, zs.vyhier*nvl(tr.bodyvyhra,0)+zs.remiz*nvl(tr.bodyremiza,0) body, zs.vyhier,zs.remiz,zs.prehier,sl.dali,sl.dostali from
tim t join
ligatim lt on t.id=lt.tim join
liga l on lt.liga=l.id join
sport s on l.sport=s.id join
trvanie tr on s.trvanie=tr.id inner join
zapasstat zs on zs.liga=l.id and t.id=zs.tim inner join
skoreliga sl on sl.liga=l.id and sl.tim=t.id
order by
case
when tr.bodyvyhra is null then (zs.vyhier+0.5*zs.remiz)/ZS.ZAPASOV desc,ZS.VYHIER desc
else body desc, zs.vyhier desc, sl.dali desc
end;
please help, thanks

The desc and asc keywords are not allowed in the case. Plus, only one column at a time is allowed. You can try this:
order by (case when tr.bodyvyhra is null then (zs.vyhier+0.5*zs.remiz)/ZS.ZAPASOV else body end) desc,
ZS.VYHIER desc,
sl.dali desc
Note that this assumes that body is of a numeric type.

Replace
order by
case
when tr.bodyvyhra is null then (zs.vyhier+0.5*zs.remiz)/ZS.ZAPASOV desc,ZS.VYHIER desc
else body desc, zs.vyhier desc, sl.dali desc
end;
with
order by
case when tr.bodyvyhra is null then (zs.vyhier+0.5*zs.remiz)/ZS.ZAPASOV end desc,
case when tr.bodyvyhra is not null then body end desc,
ZS.VYHIER end desc,
case when tr.bodyvyhra is not null then sl.dali end desc;
I split your order by in several cases because:
1) case can contain only expressions (or conditons)
2) expressions must be in one "type group"

Related

Error in order clause of partition by when using multiple case statement

I want to use multiple case statement inside order by clause in partition by statement.
I have many columns so ,I am only posting the required one.
I have table customers which has:
Select
name,
ROW_NUMBER() OVER(PARTITON BY lastname, rollno
ORDER BY
CASE
WHEN
NVL(gender, address) IS NULL
then
a.effdate desc
else
CASE
WHEN
NVL(a.postoffc, a.mon) <= file.effdate
then
file.effdate
else
a.postoffc
END
desc, NVL(l4.covcode, a.pass)
end
)
rn
from
customers a;
If,i remove these case statement then my join with other tables and query is working fine.So,there is no problem in join statement or any other logic.The problem I get is when i used multiple case statement.I think my syntax is mistake.Please tell me how can solve this error.I need this case statement logic as mandatory.
You need to close the second CASE block before you declare the other ordering criteria. Also, you have an unwanted DESC within the expression, that should be placed after it.
ORDER BY
CASE
WHEN NVL(gender, address) IS NULL THEN a.effdate
ELSE CASE
WHEN NVL(a.postoffc, a.mon) <= file.effdate THEN file.effdate
ELSE a.postoffc
END
END desc, --> here
NVL(l4.covcode, a.pass)
But overall, I don't think that you need to nest the case expressions. This should work equally well, and is easier to follow:
ORDER BY
CASE
WHEN NVL(gender, address) IS NULL THEN a.effdate
WHEN NVL(a.postoffc, a.mon) <= file.effdate THEN file.effdate
ELSE a.postoffc
END desc,
NVL(l4.covcode, a.pass)

How to order by multiple columns in sql

I need help ordering my results, probably with a combination of case statements. Please see image showing existing output, conditions, desired output. Exhibited in Excel for ease, but actually done in SQL. The ORDER BY clause is what I need help on.
select
distinct
CONCAT(selection.Selid,' - ' ,Selection.Name,' - ', DevOfficer.Description,' - ', SchemeCount.[Number of Schemes],' Schemes - ',case when selection.Project=1 then '[Project] ' when selection.Project=0 then '[Selection] ' else 'Error' end,convert(varchar,selection.lastupdated,103)) [String]
, selection.selid
, selection.lastupdated
,case when selection.Project=1 then '[Project]'
when selection.Project=0 then '[Selection]'
else 'Error' end
,selection.lastupdated
from selection
inner join SelScheme on selection.SelID =selscheme.SelID
inner join DevOfficer on selection.DevOfficer = DevOfficer.DevOfficerID
inner join (select selscheme.selid ,count(selscheme.SchemeID) [Number of Schemes] from SelScheme group by SelScheme.SelID) SchemeCount on schemecount.SelID = Selection.SelID
where selection.masterselid = 0
order by
--selection.lastupdated desc,
case
when selection.Project=1 then '[Project]'
when selection.Project=0 then '[Selection]'
else 'Error' End Desc
,selid desc
,selection.lastupdated
this is the order by you need:
order by type desc,
id desc,
case when isdate(last_updated_date) then last_updated_date else 0 end desc
use asc and desc modifiers, for each order-by column you need
* Answered before code snippet added to OP question*
Although I'm unsure of SQL table name and even the actual SQL field names, the below will work.
You need to list all fields in the ORDER BY based on their priority;
SELECT
[ID]
,[Type]
,[Last Updated Date]
FROM [SCHEMA].[TABLENAME]
ORDER BY [Type] ASC, [ID] DESC, [Last Updated Date] DESC

Random sorting with ORDER BY with CASE clause

I am testing ORDER BY clause with CASE, and came across this problem.
My test select statement:
SELECT to_date as "One", field1 as "Two"
FROM(
SELECT to_date('yyyy-mm-dd', '2017-10-10'), '333' union all
SELECT to_date('yyyy-mm-dd', '2017-09-09'), '111' union all
SELECT to_date('yyyy-mm-dd', '2017-09-09'), '222' union all
SELECT to_date('yyyy-mm-dd', '2017-09-09'), '' union all
SELECT to_date('yyyy-mm-dd', '2017-09-09'), ''
)
ORDER BY One DESC,
CASE when Two = '' then 1
else 0 end DESC
And it's result may vary in a way, that sorting by second column is random:
How should I modify CASE clause to avoid it?
In Oracle, an empty string '' is the identical to NULL so your query is:
ORDER BY
One DESC,
CASE when Two = NULL then 1 else 0 end DESC
When comparing values, the are possible states are:
Equality Result
------------------------ ------
value = value TRUE
value = other_value FALSE
value = NULL NULL
NULL = NULL NULL
Your CASE expression will only evaluate to 1 when the equality evaluates to TRUE and this will never be the result when at least one side of the equality is NULL.
What you want is to use IS NULL rather than = '':
ORDER BY
One DESC,
CASE WHEN Two IS NULL THEN 1 ELSE 0 END DESC,
Two DESC;
Which you can simplify to:
ORDER BY
One DESC,
Two DESC NULLS FIRST;
The default for DESC ordering is NULLS FIRST so you could further simplify it to:
ORDER BY
One DESC,
Two DESC;
However, I would not take it this far as you are better explicitly stating that you are expecting NULL values to be ordered before non-NULL so future developers know that that is your intended ordering (rather than just an unintentional side-effect of your query).
Add the column two as third order condition
ORDER BY One DESC,
CASE when Two = '' then 1 else 0 end DESC,
Two DESC
The second order condition only puts empty entries first and not more.

Select Case is not working with Order by

I was using a simple sql query and getting an ordered list, but when I changed some of the values in the column I'm sorting by, those rows were no longer being sorted correctly.
select distinct u.Email,
case
when l.region_id is null then 'EU'
else l.region_id
end
as Location
from TB_User u
left join cat..location l on l.location=u.Location
where u.Username in (....)
order by l.region_id
I have about 5 rows that returned null for their region_id so they would be at the top of the result set. When I added the case and replaced their value, they still remain at the top. Is there anyway to make these rows sort according to their given value?
You can use CASE also in the ORDER BY. But in this case it seems that you instead want to order by the column which uses the CASE.
ORDER BY Location
If you instead want the null-regions at the bottom:
ORDER BY CASE WHEN l.region_id is null THEN 0 ELSE 1 END DESC,
Location ASC
If your rdbms doesn't support this (like SQL-Server does) you have to repeat it:
ORDER BY CASE WHEN l.region_id IS NULL THEN 'EU' ELSE l.region_id END ASC
You just order by the column value, which is null.
If you want to order by the case statement, just copy it in the order by clause:
order by
case
when l.region_id is null then 'EU'
else l.region_id end
If you are using SQL, try within the SELECT statement, use:
ISNULL(l.region_id, 'EU') AS Location
and then
ORDER BY 2
This will make your query:
SELECT DISTINCT u.Email, ISNULL(l.region_id, 'EU') AS Location
FROM TB_User u
LEFT JOIN cat..location l ON l.location=u.Location
WHERE u.Username in (....)
ORDER BY 2

SQL: Order first by table.column = 'matchingstring', then order everything else alphabetically?

I'm currently using MySQL and I want to order my book_versions records where the book_versions.name = 'paperback' show up first, and then the rest of the book_versions (book_versions.name != 'paperback') show. How would I accomplish this?
order by case when book_versions.name = 'paperback' then 0 else 1 end,
book_versions.name, -- remove this line if other names should not be ordered
book_versions.isbn
See sqlFiddle to see the difference
in mysql, you can also use field
order by field(book_versions.name, 'paperback') DESC,
book_versions.name ASC,
book_versions.isbn ASC
Try:
ORDER BY
CASE WHEN book_versions.name = 'paperback' THEN 0 ELSE 1 END, -- puts paperbacks first (because paperbacks cause this to =0, which is ordered before 1)
book_versions.name -- then order alphabetically