How to get records from table based on conditions - sql

Select only latest amount, if null then before that.
table a
customer|amount|date
001|2 |20201101
001|null|20201102
001|3 |20201103
002|8.9 |20201101
002|7 |20201008
002|null|20201106
Result
001|null|20201101
001|null|20201102
001|3 |20201103
002|null|20201101
002|null|20201008
002|7 |20201106
amount data should be taken latest as per date , other record will be null, if amount is null for the latest date it should take the previous not null value.
My current attempt:
select top 1 [amount]
from table
where [amount] is not null
order by date desc

If you want to set all but the most recent value to NULL:
select customer_code, date,
(case when seqnum = 1 then amount end) as amount
from (select t.*,
row_number() over (partition by customer_code order by (amount is not null) desc, date desc) as seqnum
from table t
) t
where customer_code = '001'
order by date desc

Probably what you are looking for is a window function:
SELECT *
FROM (SELECT *,
row_number() over
(partition by customer
order by amount desc, date desc) as rn
FROM your_table
WHERE amount is not null)
WHERE rn = 1
You can use row_number or dense_rank depending on your needs

Create a view that returns all inserted values in descending order. Then select the first or second row according to the condition.

Related

Get last and first record using rank()

I need to get first and last record (ordered by Date column) from table for certain SSID. It is not a problem if there is more records with same max or min date. All I need is union all.
I am getting last record having max(date) with:
with c as (
select *, rnk = rank() over (partition by Date order by Date ASC)
from table
where SSID = '00921834800'
)
select top 1 Date, City, Title
from c
order by Date desc
How to I get first record (min(Date)) as well (same thing only with order by Date asc) with single select and without using ranking again?
I'm using MSSQL 2017.
; with c as (
select *,
rnk = rank() over (partition by Date order by Date ASC),
rnk2 = rank() over (partition by Date order by Date desc)
from table
where SSID= '00921834800'
)
select Date,
City,
Title
from c
where rnk = 1 or rnk2 = 1
order by Date desc
I would use the following query:
select * from (select top 1 with ties * from t where ssid = '00921834800' order by date) as a
union all
select * from (select top 1 with ties * from t where ssid = '00921834800' order by date desc) as b
One other solution is :
with
c as
(
select *,
rank() over (partition by Date order by Date ASC) AS RNK,
count() OVER (partition by Date) AS CNT
from table
where SSID= '00921834800')
select Date, City, Title
from c
WHERE RNK = 1
OR CNT = RNK
order by Date desc

How to filter to get one unique record using SQL

I have a table similar to this. If there is a confirmed record, I want to select the oldest record and if not, select the most recent one. In this case, I would want the 4_A record.
ID
Record
Type
Date
1_A
1
auto
4/7/2021
2_A
1
confirmed
4/1/2021
3_A
1
suggested
4/5/2021
4_A
1
confirmed
4/2/2021
5_A
1
suggested
4/5/2021
I've been able to use the a window function and QUALIFY to filter the most recent one but not sure how to include the TYPE field into the mix.
SELECT * from TABLE WHERE QUALIFY ROW_NUMBER() OVER (PARTITION BY RECORD ORDER BY RECORD,DATE DESC) = 1 ;
Let me assume that you mean the oldest confirmed date if there is a confrimed:
SELECT *
FROM TABLE
WHERE QUALIFY ROW_NUMBER() OVER (PARTITION BY RECORD
ORDER BY (CASE WHEN Type = 'Confirmed' THEN 1 ELSE 2 END),
(CASE WHEN Type = 'Confirmed' THEN DATE END) ASC,
DATE ASC
) = 1;
If you really mean the oldest date if there is a confirmed, then:
SELECT *
FROM TABLE
QUALIFY (CASE WHEN COUNT_IF( Type = 'Confirmed') OVER (PARTITION BY RECORD)
THEN ROW_NUMBER() OVER (PARTITION BY RECORD ORDER BY DATE)
THEN ROW_NUMBER() OVER (PARTITION BY RECORD ORDER BY DATE DESC)
END) = 1;

how To Select with group by and order by clause?

I need to select from table by using group by clause and then order by clause
select id,EXID,Rate,Date,Currency from tb_exchange where Boolean='True' group by id,EXID,Rate,Date,Currency ORDER BY id DESC
But it return normally like
select * from tb_exchange where Boolean='True' ORDER BY id DESC
I need to return the newest item first and it groups by currency name. My Currency Name are (THB and USD )
Please help me,
thank in advance.
You may try using ROW_NUMBER here:
SELECT id, EXID, Rate, Date, Currency
FROM
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY Currency ORDER BY Date DESC) rn
FROM tb_exchange
WHERE Boolean = 'True'
) t
WHERE rn = 1
ORDER BY id DESC;
This answer assumes that you want the latest record from each Currency group and that the Date column records how recent or old a given record is.

Decode maximum number in rows for sql

I am using the #standardsql in bigquery and trying to code the maksimum ranking of each customer_id as 1, and the rest of it are 0
This is the query result so far
The query for ranking is this
ROW_NUMBER() OVER(PARTITION BY customer_id ORDER BY booking_date Asc) as ranking
What i need is to create another column like this where it decode the maximum ranking of each customerid as 1, and the number below it as 0 just like the below table
Thanks
Based on your sample data, your ranking is unstable, because you have multiple rows with the same key values. In any case, you can still do what you want without subqueries, just using case:
select t.*,
row_number() over (partition by customer_id order by booking_date asc) as ranking,
(case when row_number() over (partition by customer_id order by booking_date asc) =
count(*) over (partition by customer_id)
then 1 else 0
end) as custom_coded
from t;
A more traditional way of doing essentially the same thing would be to use a descending sort:
select t.*,
row_number() over (partition by customer_id order by booking_date asc) as ranking,
(case when row_number() over (partition by customer_id order by booking_date desc) = 1
then 1 else 0
end) as custom_coded
from t;
We can wrap your current query, and then use MAX as an analytic function with a partition by customer to compare each ranking value against the max ranking for each customer. When the ranking value equals the maximum value for a customer, then we assign 1 for the custom_coded, otherwise we assign 0.
SELECT
customer_id, item_bought, booking_date, ranking,
CASE WHEN ranking = MAX(ranking) OVER (PARTITION BY customer_id)
THEN 1 ELSE 0 END AS custom_coded
FROM
(
SELECT customer_id, item_bought, booking_date,
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY booking_date) ranking
FROM yourTable
) t;

SQL - pull unique name with the lastest date and lowest value

how do i get unique name with the latest date and lowest value.
Name date value
brad 1/2/10 1.1
brad 1/2/10 2.3
bob 1/6/10 1.0
brad 2/4/09 13.2
this query does not seem to work
SELECT distinct
A.[ViralLoadMemberID]
,B.LastName
,B.FirstName
,A.[Date]
,A.[vaule]
FROM [t].[dbo].[tblViralLoad] A
left join [dbo].[tblEnrollees] B on A.ViralLoadMemberID = B.MemberID
where
A.Date =
(
select MAX(Date)
from dbo.tblViralLoad
where ViralLoadMemberID = A.ViralLoadMemberID
and
( Date >= '07/01/2014'
and Date <= '12/3/2014' ) )
The idea is to use order by and fetch only one row. If you want the lowest value on the latest date, the standard SQL would be:
select t.*
from table t
order by desc desc, value asc
fetch first 1 row only;
For older versions of SQL Server, you would omit the last line and do select top 1 * . . .. For MySQL, the last line would be limit 1.
Fun with rank()
declare #t as table (name varchar(50),dte date,val decimal(18,10));
insert into #t(name,dte,val) values
('Dave','1/1/2015',1.0),
('Dave','1/3/2015',1.2),
('Dave','1/4/2015',1.5),
('Dave','1/10/2015',1.3),
('Dave','1/15/2015',1.2),
('Steve','1/11/2015',1.6),
('Steve','1/12/2015',1.1),
('Steve','1/15/2015',1.2),
('Bill','1/21/2015',1.9),
('Ted','1/1/2015',1.8),
('Ted','1/10/2015',1.0),
('Ted','1/12/2015',1.7)
-- This will show the lowest prices by each person
select name,dte,val from (select name,dte,val, rank() over (partition by name order by val) as r from #t) as data where r = 1
-- This will be users lowest price and the last day they sublitted a prices regurdless if it is the lowest
select name,max(dte) as [last Date] ,min(val) as [Lowest Value] from #t group by name
-- Who had the lowest price last regurdless if they have raised there price later.
select top(1) name,dte [last lowest quote],val from (select name,dte,val, rank() over (order by val) as r from #t) as data where r = 1 order by dte desc
-- what is the lowest price cueently quoted reguarless who quoted it
select top(1) name,dte [best active quote],val from (select name,dte,val, rank() over (partition by name order by dte desc) as r from #t) as data where r = 1 order by val