I want to create a query that assigns row numbers per ID in a database table, and certain specific values always get fixed row numbers. For instance, if the value in col2 is A, then the row number should be consistently set to 1. Similarly, if col2 contains the value B, then the row number should always be 2. All other values in col2 should be assigned row numbers in consecutive order starting from 3.
Desired result:
myid col1 col2 row_number
----------------------------------
1 foo A 1
1 bar B 2
1 foobar C 3
1 foobar D 4
2 foobar A 1
2 foob X 3
3 hello B 2
3 hello Z 3
3 hi Y 4
Here is an example which is not working properly.
Sounds like you want to start the row_number with a specific offset, ignoring constant values and assigning them a constant row number.
You can do something a bit ugly like this:
SELECT myid, col1, col2,
case
when col2 = 'A' then 1
when col2 = 'B' then 2
else row_number() over (partition by myid
order by case when col2 = 'A' then 'ZZZ'
when col2 = 'B' then 'ZZZ1'
else col2
end) + 2
end as row_number
FROM newtable
ORDER BY myid, row_number
Result:
MYID COL1 COL2 ROW_NUMBER
1 foo A 1
1 bar B 2
1 foobar C 3
1 foobar D 4
2 foobar A 1
2 foob X 3
3 hello B 2
3 hello Y 3
3 hello Z 4
This start the row number from +2 (Depending on the number of constant values [A,B]), giving each constant value a value that will be sorted last in the row_number window function so the rest will be sorted first.
I'm struggle with SQL RANK function. Can some help me figured this out .
its possible to get my desire column?
that's my rank query, last column its my output. i want achieve output from column 3
RANK() OVER ( PARTITION BY col1 ORDER By col2)
col1 col2 "desired output" "current output"
A 1 1 1
A 1 1 1
A 1 1 1
A 1 1 1
A 1 1 1
A 5 2 6
B 3 1 1
DENSE_RANK() OVER ( PARTITION BY col1 ORDER By col2)
that was the answer, thx anyway
Let's say I have the following
Col1 Col2
1 A
1 A
1 A
1 B
1 B
1 B
1 B
2 A
2 A
2 B
3 A
3 A
3 A
3 A
3 A
3 A
What i need to do is write a query that determines the number of records for each combination of Col1 and Col2 and divide 1 by that number and assign that value to a new column (Col3), however I also need to update records in some cases so when summing the new column it always adds to one for each combination of Col1 and Col2.
So, in the first step I would end up with
Col1 Col2 NumberofRows
1 A 3
1 B 4
2 A 2
2 B 1
3 A 6
which when dividing by 1 produces
Col1 Col2 Col3
1 A 0.33
1 A 0.33
1 A 0.33
1 B 0.25
1 B 0.25
1 B 0.25
1 B 0.25
2 A 0.5
2 A 0.5
2 B 1
3 A 0.17
3 A 0.17
3 A 0.17
3 A 0.17
3 A 0.17
3 A 0.17
However when summing Col3 where Col1 = 1 and Col2 = A we end up with 0.99 instead of 1 for obvious reasons. Similarly, summing Col3 where Col1=3 and Col2=A we end up with 1.02.
How can I do this?
SQL Server can only store exact numbers if they can be expressed as a whole integer divided by a multiple of ten. Since one third cannot be expressed that way, SQL Server cannot store one third without loss of precision.
A better option would be to store the row count. Row counts are whole numbers and SQL Server can store them without loss of precision. They will add up exactly to the total amount of rows. And if you display the row, you can display 1/rc. What you display will never add up to one, but that is a limitation of displaying a number in decimal form.
If it's okay to display the number as a fraction, you could:
select '1/' + cast(rc as varchar(20))
I tried using CTE.
Please check my approach below :
;WITH c1
AS
( SELECT col1, col2, count(*) as Cnt
FROM test
GROUP BY col1, col2
),
c2
AS
( SELECT t.col1, t.col2, cast(cast(1 as decimal(5, 2))/grpCount.Cnt as decimal(5, 2))
AS Cnt, 1%grpCount.Cnt AS roundedCount
FROM test t
JOIN (SELECT * FROM c1) AS grpCount
ON grpCount.col1 = t.col1 AND grpCount.col2 = t.col2
)
SELECT * FROM c2;
SQL Fiddle :- http://sqlfiddle.com/#!6/fe268/7
You need to make sure that SQL uses the intermediate values as floats, but then cast to decimal 2 d.p when you display
SQL Fiddle
MS SQL Server 2012 Schema Setup:
CREATE TABLE tableA
(
Col1 int,
Col2 VARCHAR(1)
)
INSERT INTO tableA
VALUES
(1,'A'),
(1,'A'),
(1,'A'),
(1,'B'),
(1,'B'),
(1,'B'),
(1,'B'),
(2,'A'),
(2,'A'),
(2,'B'),
(3,'A'),
(3,'A'),
(3,'A'),
(3,'A'),
(3,'A'),
(3,'A')
Query 1:
;WITH cnt
AS
(
SELECT Col1, Col2, 1.0 / COUNT(*) cnt
FROM tableA
GROUP BY Col1, Col2
)
SELECT A.Col1, A.Col2, CAST(SUM(cnt) AS decimal(4,2))
FROM tableA A
INNER JOIN cnt
ON A.Col1 = cnt.Col1 AND A.Col2 = cnt.Col2
GROUP BY A.Col1, A.Col2
Results:
| COL1 | COL2 | COLUMN_2 |
|------|------|----------|
| 1 | A | 1 |
| 1 | B | 1 |
| 2 | A | 1 |
| 2 | B | 1 |
| 3 | A | 1 |
I have requirement, where i have to give rownumber for each record returned by my query based on the total count of the rows returned.
lets say a rownumber for each 3 record.
for ex.
colA colB colC(rowno)
1 abc 1
2 asd 1
3 asw 1
4 tre 2
5 cfr 2
6 dfr 2
7 sdf 3
I tried with row_number() over (partition by count(*) order by colA) but it gives the row number as 1 for all the records.
Any idea would help.
Use some maths and the integer division rules:
select colA,colB,(ROW_NUMBER() OVER (ORDER BY colA)+2)/3 as colC
from table
The two integer constants are related - you always want the inner constant (2) to be one less than the number of rows which should be assigned the same number (3).
try this
SELECT ROW_NUMBER() OVER (Order by [Col]) as ColID FROM [TABLE NAME]
WHERE colC = 3
Given a table with:
ID VALUE
-- -----
1 1
2 2
3 3
4 4
I would like to compute something like this:
ID VALUE SUM
-- ----- ---
1 1 40 -- (2-1)*2 + (3-1)*3 + (4-1)*4 + (5-1)*5
2 2 26 -- (3-2)*3 + (4-2)*4 + (5-2)*5
3 3 14 -- (4-3)*4 + (5-3)*5
4 4 5 -- (5-4)*5
5 5 0 -- 0
Where the SUM on each row is the sum of the values of each subsequent row multiplied by the difference between the value of the subsequent row and the current row.
I could start with something like this:
CREATE TABLE x(id int, value int);
INSERT INTO x VALUES(1, 1);
INSERT INTO x VALUES(2, 2);
INSERT INTO x VALUES(3, 3);
INSERT INTO x VALUES(4, 4);
INSERT INTO x VALUES(5, 5);
SELECT id, value
,SUM(value) OVER(ORDER BY id ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING) AS sum
FROM x;
id | value | sum
----+-------+-----
1 | 1 | 14
2 | 2 | 12
3 | 3 | 9
4 | 4 | 5
5 | 5 |
(5 rows)
where each row has the sum of all subsequent rows. But to take it further, I would really want something like this pseudo code:
SELECT id, value
,SUM( (value - FIRST_ROW(value)) * value )
OVER(ORDER BY id ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING) AS sum
FROM x;
But this is not valid. And that is the crux of the question: is there a way to reference multiple rows in the window of an analytic function? Or a different way to approach this? The example above is contrived. I was actually playing with an interesting puzzle from another post Rollup Query which led me to this problem. I am trying this in Postgresql 9.1, but not bound to that.
Not quite sure if I've understood your requirement exactly here, but the query that you want is something like
select a.id, a.value, sum(( b.value - a.value ) * b.value )
from x a, x b
where a.id < b.id
group by a.id, a.value
Hope that helps.