Here is my problem: I have a list of flagged values, I want to see where those values would be in the case they weren't flagged. But I don't want the other flagged values to influence the order.
Note: Flagged values are the ones with CurrentPlace 10000
ID Value CurrentPlace
------------------------
1 2 1
2 8 3
3 3 2
4 4 10000
5 5 10000
6 10 10000
Using:
select *
from
(select
id, value,
rank() over (order by Value asc) as Rank
from
tbl1) r
where
r.ID in (select id from tbl1 where CurrentPlace = 10000)
Desired output:
ID Value Rank
------------------
4 4 3
5 5 3
6 10 4
But I'm getting this instead:
ID Value Rank
------------------
4 4 3
5 5 4
6 10 6
Any help will be appreciated
Thank you guys
I've solved with
SELECT ID, Value, Rank
FROM tbl1 a
CROSS APPLY
(SELECT isnull(max(currentPlace),0) + 1 AS Rank FROM tbl1 WHERE value < a.value and currentPlace <> 10000) b
WHERE a.CurrentPlace = 10000
Please feel free to comment this out.
Related
I am working on a query for SQL Server 2005 that needs to return data with two 'index' fields. The first index 't_index' should increment every time the 'shade' column changes, whilst the second index increments within the partition of the values in the 'shade' column:
t_index s_index shade
1 1 A
1 2 A
1 3 A
1 4 A
1 5 A
2 1 B
2 2 B
2 3 B
2 4 B
2 5 B
To get the s_index column I am using the following:
Select ROW_NUMBER() OVER(PARTITION BY [shade] ORDER BY [shade]) as s_index
My question is how to get the first index to only increment when the value in the 'shade' column changes?
That can be accomplished with the DENSE_RANK() function:
DENSE_RANK() OVER(Order By [shade]) as t_index
You can try to use DENSE_RANK() for that:
SELECT
shade,
s_index = ROW_NUMBER() OVER(PARTITION BY [shade] ORDER BY [shade]),
t_index = DENSE_RANK() OVER (ORDER BY [shade])
FROM dbo.YourTableNameHEre
Gives output:
shade s_index t_index
A 1 1
A 2 1
A 3 1
A 4 1
A 5 1
B 1 2
B 2 2
B 3 2
B 4 2
B 5 2
ID
value
1
4
1
5
3
4
2
10
I want to add another column called count, that has for each id the number of observations.
Transformed table
id
value
count
1
4
2
1
5
2
3
4
1
2
10
1
You can use the OVER() clause to aggregate.
SELECT
ID,
value,
[count] = COUNT(*) OVER (PARTITION BY ID)
FROM dbo.TableName;
I have a set of data that I want to classify into groups based on a prior record id existing on the newer rows. The initial record of the group has a prior sequence id = 0.
The data is as follows:
customer id
sequence id
prior_sequence id
1
1
0
1
2
1
1
3
2
2
4
0
2
5
4
2
6
0
2
7
6
Ideally, I would like to create the following grouping column and yield the following results:
customer id
sequence id
prior sequence id
grouping
1
1
0
1
1
2
1
1
1
3
2
1
2
4
0
2
2
5
4
2
2
6
0
3
2
7
6
3
I've attempted to utilize island gap logic utilizing the ROW_NUMBER() function. However, I have been unsuccessful in doing so. I suspect the need here is more along the lines of a recursive CTE, which I am attempting at the moment.
I agree that a recursive CTE will do the job. Something like:
WITH reccte AS
(
/*query that determines starting point for recursion
*
* In this case we want all records with no prior_sequence_id
*/
SELECT
customer_id,
sequence_id,
prior_sequence_id,
/*establish grouping*/
ROW_NUMBER() OVER (ORDER BY sequence_id) as grouping
FROM yourtable
WHERE prior_sequence_id = 0
UNION
/*join the recursive CTe back to the table and iterate*/
SELECT
yourtable.customer_id,
yourtable.sequence_id,
yourtable.prior_sequence_id,
reccte.grouping
FROM reccte
INNER JOIN yourtable ON reccte.sequence_id = yourtable.prior_sequence_id
)
SELECT * FROM reccte;
It looks like you could use a simple correlated query, at least given your sample data:
select *, (
select Sum(Iif(prior_sequence_id = 0, 1, 0))
from t t2
where t2.sequence_id <= t.sequence_id
) Grouping
from t;
See Example Fiddle
I have SQL data table with following data structure
ID Hrly Hshed Dust_removal_to_done Dust_removal_done Update_datetime
2 ER MGS 4 4 2009-05-05
3 ER AQ 4 2 2009-05-05
4 SR ANDA 4 4 2009-05-05
5 ECR HOME 5 5 2009-05-05
6 NR GZB 5 5 2009-05-05
7 NR LDH 5 5 2009-05-05
8 NCR JHS 5 5 2009-05-05
9 NCR CNB 5 5 2009-06-05
10 SCR LGD 5 5 2009-06-05
11 SCR LGD 5 5 2009-05-05
the data is fed by users on daily basis.
Further I am using a stored procedure for cumulative sum of 'Dust_removal_done' as
ALTER PROCEDURE [dbo].[RAP_regular] as
SELECT Hshed, HRly, Dust_removal_to_done, Dust_removal_done, (SELECT SUM(Dust_removal_done) FROM TPHRAP_regular t2
where t2.Hshed = TPHRAP_regular.Hshed and t2.Update_datetime <= TPHRAP_regular.Update_datetime) as cumulative_dust_removal
FROM TPHRAP_regular
This stored procedure is giving me result as under
Hshed Hrly Dust_removal_to_done Dust_removal_done cumulative_dust_removal
MGS ER 4 4 4
AQ ER 4 2 2
ANDA SR 4 4 4
HOME ECR 5 5 5
GZB NR 5 5 5
LDH NR 5 5 5
JHS NCR 5 5 5
CNB NCR 5 5 5
LGD SCR 5 5 10
LGD SCR 5 5 5
This is working fine. Now the issue is that there are only 9 Hsheds and therefore I want to display only 9 latest records (unique Hshed along with cumulative column) in my grid view as final result so that no Hshed will repeate in the table. How to achieve this? please help.
You need to change your stored procedure(Has to be in it since you are discarding the date field in it).
You can use ROW_NUMBER() window function to filter only the latest records, like this:
SELECT Hshed,HRly,Dust_removal_to_done,Dust_removal_done,cumulative_dust_removal
FROM(
SELECT Hshed, HRly, Dust_removal_to_done, Dust_removal_done,
(SELECT SUM(Dust_removal_done) FROM TPHRAP_regular t2
where t2.Hshed = TPHRAP_regular.Hshed
and t2.Update_datetime <= TPHRAP_regular.Update_datetime) as cumulative_dust_removal,
ROW_NUMBER() OVER (PARTITION BY Hshed ORDER BY Update_datetime DESC) as rnk
FROM TPHRAP_regular)
WHERE rnk = 1
EDIT: You should also use SUM() OVER(..) for cumulative sum , no need to select from the table twice:
SELECT t.Hshed,
t.HRly,
t.Dust_removal_to_done,
t.Dust_removal_done,
t.cumulative_dust_removal
FROM (SELECT Hshed,
HRly,
Dust_removal_to_done,
Dust_removal_done,
SUM(Dust_removal_done) OVER(PARTITION BY Hshed ORDER BY Update_datetime) as cumulative_dust_removal,
ROW_NUMBER() OVER(PARTITION BY Hshed ORDER BY Update_datetime DESC) as rnk
FROM TPHRAP_regular) t
WHERE t.rnk = 1
In SQL Server 2008 R2, I have a table like this:
ID Dates Count
1 03-02-2014 2
2 04-02-2014 1
3 05-02-2014 NULL
4 06-02-2014 1
5 07-02-2014 3
6 08-02-2014 NULL
7 09-02-2014 2
8 10-02-2014 NULL
9 11-02-2014 1
10 12-02-2014 3
11 13-02-2014 NULL
12 14-02-2014 1
I have an INT variable having some value such as #XCount = 15.
My requirement is to update the count column with (#XCount - Count) such as the result of previous record will be subtracted by the Count value in the next record.
Result:
ID Dates Count
1 03-02-2014 13 (15-2)
2 04-02-2014 12 (13-1)
3 05-02-2014 12 (12-0)
4 06-02-2014 11 (12-1)
5 07-02-2014 8 (11-3)
6 08-02-2014 8 (8-0)
7 09-02-2014 6 (8-2)
8 10-02-2014 6 (6-0)
9 11-02-2014 5 (6-1)
10 12-02-2014 2 (5-3)
11 13-02-2014 2 (2-0)
12 14-02-2014 1 (2-1)
I'm reluctant to use cursors as a solution. Can somebody help me?
How about something like
DECLARE #XCount INT = 15
;WITH Vals AS(
SELECT ID, Dates, [Count] OriginalCount, #XCount - ISNULL([COUNT],0) NewCount
FROM Table1
WHERE ID = 1
UNION ALL
SELECT t.ID, t.Dates, t.[Count], v.NewCount - ISNULL(t.[Count],0)
FROM Table1 t INNER JOIN Vals v ON t.ID = v.ID + 1
)
SELECT *
FROM Vals
SQL Fiddle DEMO
Do note thought that this is a recursive query, and that sometimes (until the tech allows for it, such as SQL SERVER 2012 LAG or Running totals) old does work.