sql descending alphabetical inside order by case example (firebird) - sql

This needs to be done in Firebird with FlameRobin
my problem is very simple but I stil need help with it
Select * from Clients
order by Case town
when 'amsterdam' Then 1
when 'rotterdam' Then 2
when 'maastricht' Then 3
else 4 end,
Case Gender
when null then 1
when 'Male' then 2
when 'Female' then 3
else 4 end,
---From Here it goes wrong what I want--
Case name
when null then 1
when asc then 2 ( and here I want the names alphabetical descending )
else 3 end
because sql is so limited I need to some help here

I think you are better off building those calculated fields in your select and then working with them for ordering like this:
SELECT *,
(CASE town
WHEN 'amsterdam' THEN 1
WHEN 'rotterdam' THEN 2
WHEN 'maastricht' THEN 3
ELSE 4
END CASE) as town_order,
CASE gender
WHEN ...
...
ELSE 4
END CASE) as gender_order,
CASE gender
WHEN ...
...
ELSE 3
END CASE) as name_order
ORDER BY town_order ASC, gender_order ASC, name_order ASC, name DESC
Of course this would be a VERY non-optimal query, not able to use any sort of indexes for sorting. If you really want to query efficiently, you should add specific town_order, gender_order, etc. fields to your table and place indexes on them.

Related

Order By Case With Text

I have a table of subjects which I need to sort - if the subject is a core subject then it needs to come first (sorted by SortOrder), if it is not a core subject then it needs to sorted alphabetically.
I've set up a fiddle with an example table: http://sqlfiddle.com/#!18/4b80eb/1
And the code I've tried is:
SELECT * FROM subject
ORDER BY CASE
WHEN IsCore=1 THEN SortOrder
ELSE [Description]
END
I get this error 'Conversion failed when converting the varchar value 'Science' to data type int.'.
I was hoping to get subjects in the following order:
Maths
Reading
Writing
Art
Computing
Science
Can anybody suggest how I should be doing the sort?
A CASE expression returns a scalar value, and uses data type precedence to determine the return type. Clearly SortOrder is an int, and so has a higher data type precedence that the varchar datatype that Description is. Therefore you need to use a few expressions. I assume you want rows that have IsCore = 1 first, which are then ordered by SortOrder, and then use the column Description.
ORDER BY CASE WHEN IsCore = 1 THEN 0 ELSE 1 END,
CASE WHEN IsCore = 1 THEN SortOrder END,
Description;
Assuming IsCore is always 0/1, you could express this using a single condition as:
ORDER BY ROW_NUMBER() OVER (ORDER BY IsCore DESC,
SortOrder * - IsCore,
Description
)
Or:
ORDER BY ORDER BY IsCore DESC,
SortOrder * - IsCore,
Description
Here is a SQLfiddle.
However, Larnu's solution is the more interpretable one.
Here is how I would do it:
SELECT [SubjectId], [SortOrder], [Description], [IsCore]
FROM subject
ORDER BY IsCore DESC, -- Everything with 1 in IsCore will come first
CASE WHEN IsCore = 1
THEN [SortOrder] -- use SortOrder for IsCore 1
ELSE ROW_NUMBER() OVER(ORDER BY [Description]) -- row number is alphabeticaly oredered
END
Note that a case expression must return compatible data type in all it's branches, meaning that it only returns a single data type, which is the highest precedence type from the set of types in all it's branches.
Like this:
SELECT * FROM subject
ORDER BY
IsCore DESC,
CASE IsCore WHEN 1 THEN [SortOrder] END,
[Description]
The CASE statement is needed only to sort the rows with IsCore = 1.
See the demo.
Results:
SubjectId SortOrder Description IsCore
3 1 Maths 1
1 2 Reading 1
2 3 Writing 1
5 5 Art 0
6 6 Computing 0
4 4 Science 0

SQL Server Sorting Int Column bug

I have this SQL statement that sorts the rows depending on their change_order and change_id.
My statement looks like this:
select *
from change_dtl_from2
where chnfr_hdrno = 'CH000009'
order by
case
when chnorder is null
then 1
else 0
end asc, change_id asc
Where chnfr_hdrno is the document number, chnorder is change_order, change_id is unique key per row.
If I execute that statement, the result will be like this:
As you can see, the row with chnorder value of 5 is on the top most where the chnorder is set its order by ascending. I don't know where or what I'm doing wrong.
The default value of chnorder is null and is an int column. That's why I'm confused because whenever I add a new row, the new one will be on top most. I hope you can all help me. :)
SQL does everything correct depending on your query. With your CASE-Statement you "replace" all non-NULL-values to 1 and sort them only by change_id. If you only want to replace NULL by 1 you should use
order by (case when chnorder is null then 1 else chnordner end) asc
or you should use
order by (case when chnorder is null then 1 else 0 end) asc, chnordner asc, change_id asc

select rows from table and check if condition at column in sql

I have to check certain rows from table and check if-else condition for each rows
TABLE: report
COLUMNS :
sl.no, count, total_count, calls
Sample Data:
sl.no count total_count calls
----------- ----------- ----------- -----------
1 2 6 4
2 2 7 5
3 4 9 3
Here i have to check if condition
if total_count > 6
select 'Y
else
select 'N'
I get correct answer for single row. If there is multiple row it can't check all, it check only last row of my table.
Use CASE expression
SELECT
*,
CASE WHEN total_count > 6 THEN 'Yes' ELSE 'N' END
FROM report
You must use CASE.It work like if-else in t-SQL. MSDN
For example:
SELECT [num],[count], [total_count], [calls], CASE WHEN [total_count] > 6 THEN 'Y' ELSE 'N' END FROM t
You could use CASE. You can read documentation.
SELECT *,
CASE WHEN total_count > 6 THEN 'Y' ELSE ' N' END
FROM Report
The SQL version of "inline if" is CASE:
SELECT
*,
CASE WHEN total_count > 6 THEN 'Y'
ELSE 'N'
END AS IsTotalCountGreaterThanSix
FROM YourTable;

Multiple Order By Relationships, one a case

I have a conditional query as such:
If a column (order) is not 0, order by value 1 to 99999 (max)
I need to order all 0s in order by last name.
So if I have a table as such
ID Order Last Name
1 0 Manner
2 1 Brock
3 0 Lester
4 0 Annual
5 0 Greatly
The results I expect are:
Brock
Annual
Greatly
Lester
Manner
Here is my query. What is happening every time is that I am getting last name sort, without the non-order 0 going first:
select c.last_name
from person_reports crt
join person c
where c.org_id = 1000 and crt.reports_to_id = 100389 and c.id = crt.contact_id
order by c.last_name, case preference_num when 0 then 9999999 else preference_num end
Results of my current work:
Annual
Brock
Greatly
Lester
Manner
Thanks for any help
You can simply reverse the ORDER BY clause to:
order by case preference_num when 0 then 9999999 else preference_num end, c.last_name
And you can avoid using the magic '9999999' if you add one more segment at the beginning:
order by case preference_num when 0 then 1 else 0 end, preference_num, c.last_name

Ordering Select clause result in specific way

I need help with writing a select clause query.
For example, lets say I have a query like that:
select value from some_table order by value asc;
as a result I get this:
1
2
3
4
5
6
7
8
9
10
but a special query I want to write, is the one which still will give me sorted values, but will put 5 after 8.
this means I need one value to be out of regular order.
it can be described in other way. lets say I have two groups of numbers (example):
A={ a | 1<=a<=118, a!=78 } B={ b | b>118 }
I have a group C=A U B U {78}
and I need all these values sorted like "A,78,B"
Assuming value is integer, you could do this:
SELECT *
FROM tbl
ORDER BY
CASE
WHEN value = 5 THEN 8.5
ELSE value
END
Or to expand upon DCP's answer...
SELECT *
FROM tbl
ORDER BY
CASE
WHEN (Condition for first grouping) THEN 1
WHEN (Condition for second grouping) THEN 2
WHEN (Condition for third grouping) THEN 3
ELSE 4
END
You can use multiple conditions in your order by:
ORDER BY (value BETWEEN 1 AND 118) AND value != 78 DESC,
value > 118 DESC,
value
This will ensure that values which match the first predicate come first, then values matching the second predicate, and finally values matching none of the predicates. If there is a tie (two numbers matching the same predicate) then these numbers are sorted in ascending order.
Note that I haven't tested this in Oracle. It might be necessary to wrap the predicate in a CASE expression (CASE WHEN predicate THEN 1 ELSE 0 END) to get the sorting to work in Oracle.
ORDER BY
(CASE WHEN ((value BETWEEN 1 AND 118) AND value <> 78) THEN 1 ELSE 0 END) DESC,
(CASE WHEN (value > 118) THEN 1 ELSE 0 END) DESC,
value
Order by some CASE-expression to remap your values.