Multiple Order By Relationships, one a case - sql

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

Related

Count rows with specific entry for every distinct entry of another row

So my task is to calculate some simple KPIs.
I have already accumulated a view with all the data I need.
Year_CW Is Started Needs Help
-------------------------------------
2018/45 0 1
2018/43 1 1
2018/45 0 1
2018/42 1 0
2018/45 0 1
2018/45 1 1
2018/41 0 1
2018/43 0 0
2018/45 1 1
2018/45 0 0
I then wrote the following query:
SELECT DISTINCT YEAR_CW
FROM TestView
ORDER BY YEAR_CW DESC
Which returns this
Year_CW
--------
2018/45
2018/44
2018/43
2018/42
I would now like to count for each Year_CW how often there is a 1 and how often there is a zero for both of the other rows. This may be a fairly simple question but I'm just starting with SQL and I really don't know what the keyword is for a query based on an outer query.
The other queries would be
Select Count(Is Started)
from Testview
Where Is Started = 1
And so on for the others. But I really don't know how to put them together and base them on the first query.
Thanks for your help.
select Year_CW
, sum(case when Is_Started = 1 then 1 end) as Is_Started_1
, sum(case when Is_Started = 0 then 1 end) as Is_Started_0
, sum(case when Needs_Help = 1 then 1 end) as Needs_Help_1
, sum(case when Needs_Help = 0 then 1 end) as Needs_Help_0
from Test_View
group by Year_CW
So how I did it is I created 4 new fields for you. First one is giving value ‘1’ to every field where ‘Is_Started = 1’ and then I sum the instances. I did the same for 0 values and another two fields for values 1 and 0 for ‘Needs_ Help’ column. I believe this will give you your desired result.
You seems want conditional aggregation :
select Year_CW,
sum(case when col = 1 then 1 else 0 end) as one_count,
sum(case when col = 0 then 1 else 0 end) as zero_count
from (select Year_CW, IsStarted as col
from TestView tv
union all
select Year_CW, NeedsHelp
from TestView tv
) tv
group by Year_CW
order by Year_CW desc;
So, if I'm understanding the question correctly you're just looking for the SUM of the additional two columns GROUP BY the Year_CW field. That would be the following.
SELECT Year_CW, SUM([Is Started]), SUM([Needs Help])
FROM TestView
GROUP BY Year_CW
If it's only 0 or 1, then both 0 or 1 can be summed up.
SELECT YEAR_CW,
SUM("Is Started") AS TotalStarted,
SUM(1 - "Is Started") AS TotalNotStarted,
SUM("Needs Help") AS TotalNeedsHelp,
SUM(1 - "Needs Help") AS TotalNoHelpNeeded
FROM TestView
GROUP BY YEAR_CW
ORDER BY YEAR_CW DESC

Using a case statement to show the count of two types of values in a column

SELECT
qt.name,
CASE
WHEN qr.isfinished = 0 THEN COUNT(qr.resultid)
END AS 'Attempted',
CASE
WHEN qr.isfinished = 1 THEN COUNT(qr.resultid)
END AS 'Completed'
Need it to show attempted and completed values on the same row
Name attempted Completed
--------------------------------
Algebra I 114 NULL
Algebra II 47 NULL
ASVAB 55 NULL
Algebra I NULL 69
Algebra II NULL 55
ASVAB NULL 84
Thank you for the help!
If isfinished is bit, you can't aggregate on it.
And the CASE goes inside the COUNT
SELECT qt.name,
count(Case when qr.isfinished = 0 THEN 1 END) as 'Attempted',
count(Case when qr.isfinished = 1 THEN 1 END) as 'Completed'
FROM
...
GROUP BY
qt.name
There are multiple ways you could do this, for example you could do this with joins, or you can use group by -- like so:
SELECT
qt.name,
SUM(CASE qr.isfinsihed WHEN 1 THEN 1 ELSE 0) AS 'Attempted',
SUM(CASE qr.isfinished WHEN 0 THEN 1 ELSE 0) AS 'Completed'
FROM -- what ever your from clause is, it goes here --
GROUP BY
qt.name
In order to have them on the same row, you will need to group by what they have in common. From what you have given in the question, I am assuming that is the qt.name.
Next, you can use the SUM aggregate to get each field count. All of the records that meet the criteria for each item count towards the sum, the others don't. You can also use count with 1's and Null's, I prefer using Sum because it can allow for weighted totals if I need them.

Order by inside Case in Order By

I have this database
ID Title
1 Unassaign
6 Prima
7 Adi
I want to make ID 1 to be display last but the other are sort by their title
Desired results:
ID Title
7 Adi
6 Prima
1 Unassaign
This is my code:
SELECT a.ID_WB, a.TITLE, a.DESCRIPTION, a.AUTHOR, a.DATECREATE, a.DATEUPDATE
FROM WORKBOOK a
order by case when ID_WB = 1 then 1
else 0 end
I tried insert Order By after else but it always return SQL error..
Is there a workaroud to this problem?
Thanks
PS: The first Order byshould sort by ID
Use two expressions in the order by:
order by (case when ID_WB = 1 then 1 else 0 end), title

sql descending alphabetical inside order by case example (firebird)

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.

SQL - Count( ) issue

I have a table with a charge/credit column:
Item | PriceVal | CostVal | CHARGE_CODE
1 5 3 CH
2 8 5 CH
1 -5 -3 CR
3 7 1 CH
4 15 10 CH
1 5 3 CH
I've got the query I need to get the NET price and cost, but I'm also interested in the NET charges. Right now I have:
SELECT Item, SUM(PriceVal), SUM(CostVal)
FROM Table
GROUP BY Item
How do I get another column with the value
COUNT(SUM(CHARGE_CODE=CH)-SUM(CHARGE_CODE=CR))
I'm at a loss.
count() is going to count one for every value thats not null, so I don't think thats exactly what you want. Take the count out and just take the
sum(case when charge_code = CH then costval else 0 end)
- sum(case when charge_code = 'CR' then costval else 0 end)
Since you have the dollar values entered as negatives in the table already, you can use the simple formula:
select
Item,
sum(PriceVal),
sum(CostVal),
sum(PriceVal-CostVal)
from Table
group by Item
I don't believe you should be subtracting the credit items as they're already negative.
If you really do want want the net count of transactions:
select
Item,
sum(PriceVal),
sum(CostVal),
sum(case when charge_code = 'CH' then 1 else 0 end) -
sum(case when charge_code = 'CR' then -1 else 0 end)
from Table
group by Item
or, if there are only two charge codes, substitute:
sum(case when charge_code = 'CH' then 1 else -1 end)
for the last column.
Not 100% sure what you want, but you can count only certain rows like this:
SELECT COUNT(IF(CHARGE_CODE=CH,1,NULL)) ...
And similarly sum certain values from certain rows like this:
SELECT SUM(IF(CHARGE_CODE=CH,PriceVal,0)) ...