Using "Rank()" Function I need to update the Rank based on the TotalMark but marks should not be Null - sql-server-2017

Using Rank() Function Updating the Rank to TotalMarks in null
Using Rank() Function Updating the Rank to TotalMarks is not null
I'm updating the Rank based on the TotalMarks. If the TotalMarks is not null the rank is updating but (here the issue is) it should not allow to update the Rank if the TotalMarks is null.
How to resolve this?

Just use a CASE expression
CASE WHEN TotalMarks IS NOT NULL THEN RANK() OVER (ORDER BY TotalMarks DESC) END

Related

Row_number skip values

I have a table like this:
The idea were to count only when I have "Include" at column include_appt, when it finds NULL, it should skip set is as "NULL" or "0" and on next found "Include" back to counting where it stopped.
The screenshot above I was almost able to do it but unfortunately the count didn't reset on next value.
PS: I can't use over partition because I have to keep the order by id ASC
I suggest using the DENSE_RANK() with the columns you have hidden (--*,):
SELECT
row_num AS id,
include_appt,
CASE WHEN include_appt is not null
THEN ROW_NUMBER() OVER(ORDER BY (SELECT 0))
+ 1
- DENSE_RANK() OVER(
PARTITION BY /*some hidden columns*/
ORDER BY/*some hidden columns*/)
ELSE NULL
END AS row_num2
FROM C
ORDER BY row_num
Then the result will be:
enter image description here
If you are trying to prevent row numbers being added for NULL/0 values, why not try a query like this instead?
SELECT
row_num AS id,
include_appt,
ROW_NUMBER() OVER
(
ORDER BY (SELECT 0)
) AS row_num2
FROM C
WHERE ISNULL(C.include_appt, 0) <> 0
ORDER BY row_num
I would recommend reconsidering the column names/aliases you want to have displayed in your final result to avoid confusion, but the above should effectively do what you are wanting.
You need a PARTITION BY clause
SELECT
row_num AS id,
include_appt,
CASE WHEN include_appt IS NULL
THEN 0
ELSE
ROW_NUMBER() OVER (PARTITION BY include_appt ORDER BY (SELECT 0))
END AS row_num2
FROM C
ORDER BY row_num
SELECT id, include_appt,
CASE WHEN include_appt IS NULL THEN 0
ELSE ROW_NUMBER() OVER (PARTITION BY include_appt ORDER BY id ASC)
END AS row_num
FROM #1 ORDER BY id asc
This can be easily done with a partition by include_appt as in another answer below, yet after playing around with the query plans I've decided that it is still worthwhile to consider this slightly different approach which might offer a performance boost. I believe the benefit is gained by being able to use the clustered index without involving a sort on the flag column:
select id, flag,
case when flag is not null
then row_number() over (order by id)
- count(case when flag is null then 1 end) over (order by id)
else 0 end /* count up the skips */ as new_rn
from T
order by id
Examples (including a "reset" behavior): https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=c9f4c187c494d2a402e43a3b24924581
Performance comparison:
https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=719f7bd26135ab498d11c786f1b1b28b

BigQuery/SQL: Select first row of each group

I am trying to select the first row of each group. Eg: below table I would want to keep product for www/edf/ and cate for www/abc/.
I have tried multiple ways, eg: ROW_NUMBER() OVER(PARTITION BY [...]) but somehow not getting expected outputs. The challenge for me here is that category does not have numbers as values, otherwise I can filter it down using max or min.
SELECT landing_page, ROW_NUMBER OVER ( PARTITION BY landing_page ORDER BY Page_Type DESC) AS ROW_NUM
from `xxxx.TEST.draft`
However I got this error: OVER keyword must follow a function call
Appreciate any help!
Landing_page
Page_type
www/edf/
product
www/edf/
home
www/abc/
cate
www/abc/
home
I believe you are looking for the function [FIRST_VALUE][1]?
SELECT
landing_page,
FIRST_VALUE(URL)
OVER ( PARTITION BY landing_page ORDER BY Page_Type DESC) AS first_url
FROM `xxxx.TEST.draft`
I answered my own question, sharing the code in case anyone needs:
SELECT session_id,landing_page, Page_Type, ROW_NUMBER () OVER (PARTITION BY session_id,landing_page ORDER BY Page_Type DESC) AS ROW_NUM
from `xxx._TEST.draft`
order by session_id desc

How can I assign unique value to each duplicate value in a column in a table

I have data in my table as below
Now I want to generate unique rank value to each duplicate value like 1,2,3,4 etc as below
How to do this in SQL Server 2016?
You seem to be looking for row_number():
select t.*,
row_number() over (partition by id, name order by deptid) as ranking
from t;
You can use DENSE_RANK as well,
select table.*,
DENSE_RANK() over (order by id, name ,deptid) as RANK
from table;

SQL - Window function to get values from previous row where value is not null

I am using Exasol, in other DBMS it was possible to use analytical functions such LAST_VALUE() and specify some condition for the ORDER BY clause withing the OVER() function, like:
select ...
LAST_VALUE(customer)
OVER (PARTITION BY ID ORDER BY date_x DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ) as the_last
Unfortunately I get the following error:
ERROR: [0A000] Feature not supported: windowing clause (Session:
1606983630649130920)
the same do not happen if instead of AND 1 PRECEDING I use: CURRENT ROW.
Basically what I wanted is to get the last value according the Order by that is NOT the current row. In this example it would be the $customer of the previous row.
I know that I could use the LAG(customer,1) OVER ( ...) but the problem is that I want the previous customer that is NOT null, so the offset is not always 1...
How can I do that?
Many thanks!
Does this work?
select lag(customer) over (partition by id
order by (case when customer is not null then 1 else 0 end),
date
)
You can do this with two steps:
select t.*,
max(customer) over (partition by id, max_date) as max_customer
from (select t.*,
max(case when customer is not null then date end) over (partition by id order by date) as max_date
from t
) t;

Row Number() Order Issue

Apologies in advance if this specific scenario has been asked previously, but I can't seem to get these to order properly (which is probably from staring at it for too long).
I'm using Netezza/Oracle, and In the data set below - I basically need the order_num to result in 1,2,2,2,2,3,4 (basically grouping Department and Desc1 (desc1 is not unique as there are different codes for each year, but I'm only interested in the type, not year).) Among other attempts, I've tried:
row_number () over (partition by a.department order by desc1) order_num
Which orders it alphabetically. I've also ordered by seq_no and desc1 - but that only works if I needed it alphabetically.
Thanks in advance.
Assuming that the Country is consistent with the grouping as you have shown; if you get the minimum seq_no per country in either a CTE or sub-query you can use this value in your dense_rank function, e.g.
SELECT
m.Department,
m.Desc1,
m.seq_no,
m.Country,
m.beg_date,
m.end_date,
dense_rank() OVER(PARTITION BY m.Department ORDER BY mintbl.MinSeq)
FROM dbo.mytable AS m
JOIN ( SELECT min(m.seq_no) AS MinSeq,
m.Department,
m.Country
FROM dbo.mytable AS m
GROUP BY m.Department,m.Country
) AS mintbl ON mintbl.Department = m.Department AND mintbl.Country = m.Country
ORDER BY m.seq_no
You want dense_rank() rather than row_number():
dense_rank() over (partition by a.department order by desc1) order_num
If you want to maintain the seqnum order, you can use a subquery to calculate:
min(seqnum) over (partition by department, desc1) as min_seqnum
Then in the outer query use min_seqnum for the order by.
Can you not use
dense_rank() over(partition by department, desc1 order by beg_date)
Or...
dense_rank() over(partition by department,desc1 order by seq_no)