How to write a custom sort using SQLite - sql

I have a single table
Create Table Part(Part TEXT, Rev TEXT, DateCode Date, Unique(Part,Rev))
Is it possible to perform a custom sort by DateCode DESC but for the records with same Part should be grouped together for example result:
PART_1, B, 2022-02-14
PART_1, A, 1999-01-11
PART_2, C, 2000-02-24
PART_2, B, 1998-11-12
PART_2, A, 1998-11-10
My instinct tells me it must be done with
ORDER BY CASE WHEN....
But my knowledge is not good enough to continue. Please help me.

You can use MAX() window function in the ORDER BY clause to get the max DateCode of each part and sort by that descending:
SELECT *
FROM Part
ORDER BY MAX(DateCode) OVER (PARTITION BY Part) DESC,
Part, -- just in case 2 different parts have the same max DateCode
DateCode DESC;
See the demo.

To me it looks a simple case of sorting it by Part first and Date second
SELECT * FROM Part order by Part,DateCode Desc
Sqlfiddle for SQLlite for this case here
I think I am surely missing something ..

Related

Get max(timestamp) for each group with repetition (IBM DB2)

ANSWER: Need to use LEAD and PARTITION BY functions. Please refer to Gordon's answer.
I have the following dataset :
I want to get rows 1,3,5,7 in the result set.
RESULT SET SHOULD LOOK LIKE :
11/10/2020 19:36:11.548955 IN_REVIEW
11/8/2020 19:36:11.548955 EXPIRED
11/6/2020 19:36:11.548955 IN_REVIEW
11/4/2020 19:36:11.548955 ACTIVE
Use window functions. LEAD() gets the value from the "next" row, so filter only when the value changes:
SELECT t.*
FROM (SELECT t.*,
LEAD(interac_Reg_stat) OVER (PARTITION BY Acct_No ORDER BY xcn_tmstmp) as next_interac_Reg_stat
FROM TABLE
) t
WHERE interac_Reg_stat <> next_interac_Reg_stat OR
next_interac_Reg_stat IS NULL;
Well, since you are grouping by interac_Reg_stat, you will never get 2 separate rows for the IN_REVIEW status. To get the result you want, you will need to add a sub-query to find all items with a certain interac_Reg_stat that are before another specific interac_Reg_stat.

How to select unique records from a result in oracle SQL?

I am running a SQL query on oracle database.
SELECT DISTINCT flow_id , COMPOSITE_NAME FROM CUBE_INSTANCE where flow_id IN(200148,
200162);
I am getting below results as follow.
200162 ABCWS1
200148 ABCWS3
200162 ABCWS2
200148 OutputLog
200162 OutputLog
In this result 200162 came thrice as composite Name is different in each result. But my requirement is to get only one row of 200162 which is 1st one. If result contains same flow_id multiple times then it should only display result of first flow_id and ignore whatever it has in 2nd and 3rd.
EXPECTED OUTPUT -
200162 ABCWS1
200148 ABCWS3
Could you please help me with modification of query?
Thank you in advance !!!
It appears that you want to take the lexicographically first composite name for each flow_id:
WITH cte AS (
SELECT t.*, ROW_NUMBER() OVER (PARTITION BY flow_id ORDER BY COMPOSITE_NAME) rn
FROM CUBE_INSTANCE t
WHERE flow_id IN (200148, 200162)
)
SELECT flow_id, COMPOSITE_NAME
FROM cte
WHERE rn = 1;
There is no such thing as a "first" row, unless a column specifies that information.
But you can easily use aggregation for this purpose:
select ci.flow_id, min(ci.composite_name)
from cube_instance ci
where flow_id in (200148, 200162);
group by ci.flow_id
If you do have a column that specifies the ordering, you can still use aggregation. The equivalent of the "first" function in Oracle is:
select ci.flow_id,
min(ci.composite_name) keep (dense_rank first order by <ordering col>)
from cube_instance ci
where flow_id in (200148, 200162);
group by ci.flow_id

Does Big Query support custom sorting?

I am trying to sort data by applying case when statement in the order by clause but looks like Big Query doesn't support even though it worked fine in other SQL environments. Can somebody share your thoughts on this.
Update (2021) - Bigquery now does support ORDER BY with expressions, e.g.
SELECT event_type, COUNT(*) as event_count
FROM events
GROUP BY event
ORDER BY (
CASE WHEN event='generated' THEN 1
WHEN event='sent' THEN 2
WHEN event='paid' THEN 3
ELSE 4
END
)
select x
from (
select x ,
case when x = 'a' then 'z' else x end as y
from
(select 'a' as x),
(select 'b' as x),
(select 'c' as x),
(select 'd' as x)
)
order by y desc
I think the documentation is pretty clear:
ORDER BY clause
... ORDER BY field1|alias1 [DESC|ASC], field2|alias2 [DESC|ASC] ...
The ORDER BY clause sorts the results of a query in ascending or
descending order of one or more fields. Use DESC (descending) or ASC
(ascending) to specify the sort direction. ASC is the default.
You can sort by field names or by aliases from the SELECT clause. To
sort by multiple fields or aliases, enter them as a comma-separated
list. The results are sorted on the fields in the order in which they
are listed.
So, BigQuery doesn't allow expressions in the ORDER BY. However, you can include the expression in the SELECT and then refer to it by the alias. So, BigQuery does support "custom sorting", but only by expressions in the SELECT.
Interestingly, Hive has a similar limitation.

How to Order only first 20 records in a resultset using SQL?

My requirement is to get the List of Diagnosis based on the most used Diagnosis. So, to achieve that I have added one Column named DiagnosisCounter in the tblDiagnosisMst Table of the database which increases by 1 for each Diagnosis the each time user selects it. So, my query is like below:
select DiagnosisID,DiagnosisCode,Name from tblDiagnosisMst
where GroupName = 'Common' and RecStatus = 'A' order by DiagnosisCounter desc,
Name asc
So, this query is helping me to get the list of Diagnosis but in descending order for Diagnosis and then alphabetically for Diagnosis Name. But now my client wants to show only 20 most used Diagnosis name at the top and then all the names should appear in alphabetical order. But unfortunately I am stuck in this point. It would be so appreciative if I get your helpful advice for this problem.
This should do the trick:
;With Ordered as (
select DiagnosisID,DiagnosisCode,Name,
ROW_NUMBER() OVER (ORDER BY DiagnosisCounter desc) as rn
from tblDiagnosisMst
where GroupName = 'Common' and RecStatus = 'A'
)
select * from Ordered
order by CASE WHEN rn <= 20 THEN rn ELSE 21 END,
Name asc
We use ROW_NUMBER to assign the numbers 1-x to each of the rows, based on the diagnosiscounter. We then use that value for the first ORDER BY condition if it's in 1-20, and all other rows sort equally in position 21. The second condition is then used as a tie-breaker to sort those remaining row by name.
Try this
SELECT TOP 20
* FROM tblDiagnosisMst ORDER BY DiagnosisCounter;

How to do this query in T-SQL

I have table with 3 columns A B C.
I want to select * from this table, but ordered by a specific ordering of column A.
In other words, lets' say column A contains "stack", "over", "flow".
I want to select * from this table, and order by column A in this specific ordering: "stack", "flow", "over" - which is neither ascending nor descending.
Is it possible?
You can use a CASE statement in the ORDER BY clause. For example ...
SELECT *
FROM Table
ORDER BY
CASE A
WHEN 'stack' THEN 1
WHEN 'over' THEN 2
WHEN 'flow' THEN 3
ELSE NULL
END
Check out Defining a Custom Sort Order for more details.
A couple of solutions:
Create another table with your sort order, join on Column A to the new table (which would be something like TERM as STRING, SORTORDER as INT). Because things always change, this avoids hard coding anything and is the solution I would recommend for real world use.
If you don't want the flexibility of adding new terms and orders, just use a CASE statement to transform each term into an number:
CASE A WHEN 'stack' THEN 1 WHEN 'over' THEN 2 WHEN 'flow' THEN 3 END
and use it in your ORDER BY.
If you have alot of elements with custom ordering, you could add those elements to a table and give them a value. Join with the table and each column can have a custom order value.
select
main.a,
main.b,
main.c
from dbo.tblMain main
left join tblOrder rank on rank.a = main.a
order by rank.OrderValue
If you have only 3 elements as suggested in your question, you could use a case in the order by...
select
*
from dbo.tblMain
order by case
when a='stack' then 1
when a='flow' then 2
when a='over' then 3
else 4
end