Originally I had the following query:
SELECT T.* FROM
(SELECT *, row_number() OVER
(PARTITION BY manager_id ORDER BY id) AS sn FROM my_table) T
WHERE (sn = 1)
AND ((checkbox IS NULL OR (checkbox = 0)
)
but then I added another boolean column to the db called "not_relevant" and I want to show results where its value is not 1, so I added the following:
SELECT T.* FROM
(SELECT *, row_number() OVER
(PARTITION BY manager_id ORDER BY id) AS sn FROM my_table) T
WHERE (sn = 1)
AND ((checkbox IS NULL) OR (checkbox = 0)
AND (not_relevant != 1)
)
But I get the same results even if not_relevant is 1
Why?
Related
I am trying to put conditional numbering depending on a result from row_num column.
When the flg_start_trx is 1, I would like to have new column with brand new increment by 1 and it will stop when found the end of flg_session_match != 1
How can I fix this query if I want the result should be like row_num column?
case when (title is not null and title_program is null)
then (row_number() over (partition by flg_session_match,(case when (title is not null and title_program is null) then 1 else 0 end)
)
)
end as start_session
You may try this:
(As #Ahmed mentioned above, you need a column to define an order of each row, so I've added ts for that purpose.)
SELECT * EXCEPT(par0, par1),
IF (FIRST_VALUE(flg_start_trx) OVER w1 IS NOT NULL, ROW_NUMBER() OVER w1, NULL) AS row_num
FROM (
SELECT *,
COUNT(*) OVER w0 - COUNTIF(flg_start_trx IS NULL) OVER w0 AS par0,
COUNT(*) OVER w0 - COUNTIF(flg_session_match = 1) OVER w0 AS par1
FROM sample_data
WINDOW w0 AS (ORDER BY ts)
) WINDOW w1 AS (PARTITION BY par0, par1 ORDER BY ts);
How to get first occurrence of last changed value of "sval" column?
for id = 22, 71 is the last changed value so wants to fetch first occurence of 71.
same way for id = 25, 74 is the last changed value so wants to fetch first occurence of 74.
https://dbfiddle.uk/?rdbms=mariadb_10.6&fiddle=c980809154d41f2accc9f14d569b48f1
data:
in above picture i wanted to fetch highlighted row.
try:
with LastValue as (
select t.sval
from test t
order by t.date desc
limit 1
)
select t.*
from test t
where t.sval = (select sval from LastValue)
and t.date > (select max(tt.date) from test tt where tt.sval <> (select sval from LastValue))
order by t.date asc
limit 1;
actually the problem statement is i dont want the group by sval first occurence, instead i want the whatever last changed sval so our example after highlighted rows should be returns for ids (22,25).
WITH
cte1 AS ( SELECT *,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY `date` DESC) rn1,
ROW_NUMBER() OVER (PARTITION BY id, sval ORDER BY `date` DESC) rn2
FROM test ),
cte2 AS ( SELECT *,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY `date` ASC) rn3
FROM cte1
WHERE rn1 = rn2 )
SELECT id, date, sval
FROM cte2
WHERE rn3 = 1;
https://dbfiddle.uk/?rdbms=mariadb_10.6&fiddle=a25569690e4b35a55b0bee13856eb724
One method for doing this uses lag() to check for a difference and then chooses the last point where there is a difference:
select t.*
from (select t.*,
row_number() over (partition by id order by date desc) as seqnum
from (select t.*,
lag(sval) over (partition by id order by date) as prev_sval
from test t
) t
where prev_sval is null or prev_sval <> sval
) t
where seqnum = 1;
Very importantly: This returns the last time there was a change even when the value returns to an already seen value for the id. That is how I interpret your question.
We have below table contains multiple code against the ID and CounterID. Need an output based on code and id.
Condition: Against the ID and CounterID
case 1 : if there is code CI and CO then no record
case 2 : if there is code CI and CO and CI then last record with code CI
case 3 : if there is code CI then last CI
Thanks
Rahul
You can use the analytical function as follows:
select t.* from
(select t.*, row_number() over (partition by sno order by date desc) as rn,
count(case when code = 'CI' then 1 end) over (partition by sno) as cicount,
count(case when code = 'CO' then 1 end) over (partition by sno) as cocount
from your_table t) t
where ( (cocount = 0)
or not (cicount = 1 and cocount = 1)
or (cocount > cicount ))
and rn = 1
Your logic simplifies to: The last row when it has 'CI'. One method with window functions is:
select t.*
from (select t.*,
row_number() over (partition by id order by date desc) as seqnum
from t
) t
where seqnum = 1 and code = 'CI';
You can also do this without window functions:
select t.*
from t
where code = 'CI' and
date = (select max(t2.date) from t t2 where t2.id = t.id);
I have a table which has below values:
If Sum of values = 0 with same ID I want to delete them from the table. So result should look like this:
The code I have:
DELETE FROM tmp_table
WHERE ID in
(SELECT ID
FROM tmp_table WITH(NOLOCK)
GROUP BY ID
HAVING SUM(value) = 0)
Only deletes rows with ID = 2.
UPD: Including additional example:
Rows in yellow needs to be deleted
Your query is working correctly because the only group to total zero is id 2, the others have sub-groups which total zero (such as the first two with id 1) but the total for all those records is -3.
What you're wanting is a much more complex algorithm to do "bin packing" in order to remove the sub groups which sum to zero.
You can do what you want using window functions -- by enumerating the values for each id. Taking your approach using a subquery:
with t as (
select t.*,
row_number() over (partition by id, value order by id) as seqnum
from tmp_table t
)
delete from t
where exists (select 1
from t t2
where t2.id = t.id and t2.value = - t.value and t2.seqnum = t.seqnum
);
You can also do this with a second layer of window functions:
with t as (
select t.*,
row_number() over (partition by id, value order by id) as seqnum
from tmp_table t
),
tt as (
select t.*, count(*) over (partition by id, abs(value), seqnum) as cnt
from t
)
delete from tt
where cnt = 2;
I have a table with news which I then echo into a slider using foreach loop.
I would need to adjust the sort order of the query, so the last one added (max id) is always displayed first, with others sorted by id ASC.
So example: News 1, 2, 3,4. I need them echoed like 4,1,2,3.
SELECT * FROM news ORDER BY sort ASC
How add another condition in the form of max(id) first then sort ASC?
Thanks.
You can try this query:
SELECT *
FROM (
SELECT *,
(SELECT MAX(Id) FROM news) AS max_id
FROM news) AS t
ORDER BY CASE WHEN id = max_id THEN 0 ELSE 1 END asc,
id ASC
or, using CROSS JOIN:
SELECT n.*
FROM news AS n
CROSS JOIN (SELECT MAX(Id) AS max_id FROM news) AS m
ORDER BY CASE WHEN n.id = m.max_id THEN 0 ELSE 1 END asc,
n.id ASC
or use window function
SELECT *
FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY id DESC) AS RN
FROM news) AS T
ORDER BY CASE WHEN RN = 1 THEN 0 ELSE 1 END, id
SELECT *
FROM (
SELECT *, MAX(id) OVER () AS MaxID
FROM news) AS T
ORDER BY CASE WHEN MaxID = id THEN 0 ELSE 1 END, id