Set RowNumber by grouping the value if next value is blank - sql-server

I'm using Sql Server 2008. I want to group the Data by a condition and set the RowNumber for it. None of the columns in the table are unique values.
Grouping Condition
If Any Row occurred as Blank, group the previous not null rows and set Row Number for it.
Example:
My table Data looks like this:
Code Name Location
Db1 Name1 N
Db3 Name3 S
NULL NULL NULL
Db1 Name1 N
NULL NULL NULL
Db1 Name1 N
NULL NULL NULL
Db1 Name1 S
Db4 Name4 S
I need the OUTPUT like this:
Sno Code Name Location
1 Db1 Name1 N
1 Db3 Name3 S
2 Db1 Name1 N
3 Db1 Name1 N
4 Db1 Name1 S
4 Db4 Name4 S

There is no such thing as the next row without having a column to ORDER BY. So I added an id as identity to solve this:
DECLARE #t table(id int identity(1,1), Code char(3), Name char(5), Location char(1))
INSERT #t values
('Db1','Name1','N'),('Db3','Name3','S'),(NULL,NULL,NULL),
('Db1','Name1','N'),(NULL,NULL,NULL),('Db1','Name1','N'),
(NULL,NULL,NULL),('Db1','Name1','S'),('Db4','Name4','S')
;WITH cte as
(
SELECT
row_number() over (order by id)
- row_number() over (order by id * case when code is not null then 1 end) x,
Code, Name, Location
FROM #t
)
SELECT
dense_rank() over (order by x) Sno,
Code, Name, Location
FROM cte
WHERE code is not null
Result:
Sno Code Name Location
1 Db1 Name1 N
1 Db3 Name3 S
2 Db1 Name1 N
3 Db1 Name1 N
4 Db1 Name1 S
4 Db4 Name4 S

Related

How to filter columns with multiple values for each ID in SQL Server

I have a result set as below and I want to select a single record when the same ID has 2 records with different values for Age and status column, for example
Please see the result set below where ID, name, country name coming from table A and Age, Active status coming from b table
ID name country Age status
----------------------------------------------
1 Prasad India NULL NULL
2 John USA NULL NULL
3 GREG AUS NULL NULL
4 RAVI India NULL NULL
4 RAVI India 18 Years and Above 1
Go with this:
Select *
From
(
Select t2.*,
ROW_NUMBER() over(partition by ID order by name,country,Age, status desc) as rn
From yourtable t2
)
Where rn = 1

copy same records with Different ParentID from Existing ParentID

I want to copy records from same Table. If parentID is null then I want to copy Parent and Child of that, with another parentName(I'll use replace Key word).
If it is not null then I want to copy that into same parent if same not exists in that parent only.
create table #Table(ID int primary key , Name varchar(10),ParentID int )
insert into #Table
select 1,'Suresh', -1
union
select 2,'Naresh', 1
union
select 3,'John', 1
union
select 4,'Kumar',3
union
Select 5,'Dale John',3
select * from #Table
ID Name ParentID
-------------------
1 Suresh -1
2 Naresh 1
3 John 1
4 Kumar 3
5 Dale John 3
if I select ID = 1, then all ID child should insert into same table if Name not "Suresh" and ParentID not -1.
If I select ID = 3, then ID 3 and Child should insert into same table if Name and ParentID not John & 1
Take those into Temp table and make the join between them.
IF not exists(---)
then insert into table.

Getting number of records against each row using SQL server

I have table
col1 col2
---- ----
a rrr
a fff
b ccc
b zzz
b xxx
i want a query that return number of occurrences of col1 against each row like.
rows col1 col2
---- ---- ----
2 a rrr
2 a fff
3 b ccc
3 b zzz
3 b xxx
As a is repeated 2 time and b is repeated 3 time.
You can try Count over partition_by_clause which divides the result set produced by the FROM clause into partitions to which the function is applied.
This function treats all rows of the query result set as a single group
Try this...
select count (col1) over (partition by col1) [rows] ,col1 ,col2 from tablename
You can use the OVER clause with aggregate functions like COUNT:
SELECT rows = COUNT(*) OVER(PARTITION BY col1),
col1,
col2
FROM dbo.TableName
Demo

Bringing categories into table rows without using cursors

I got a table containing 3 columns:
NameColumn CategoryColumn QuantityColumn
Name1 Category1 5
Name2 Category1 8
Name3 Category1 10
Name4 Category2 3
Name5 Category2 15
Name6 Category2 7
I need to write a query to convert the above data into the following result set:
NameColumn CategoryColumn QuantityColumn
Category1 NULL NULL
Name1 NULL 5
Name2 NULL 8
Name3 NULL 10
Category2 NULL NULL
Name4 NULL 3
Name5 NULL 15
Name6 NULL 7
Is there anyway to do this without using cursors?
Thanks.
SELECT NameColumn, CategoryColumn, QuantityColumn
FROM
(
SELECT CategoryColumn AS NameColumn, NULL AS CategoryColumn, NULL AS QuantityColumn,
CategoryColumn AS _cat, 1 AS _iscat
FROM myTable
GROUP BY CategoryColumn
UNION ALL
SELECT NameColumn, NULL AS CategoryColumn, QuantityColumn,
CategoryColumn AS _cat, 0 AS _iscat
FROM myTable
) x
ORDER BY _cat, _iscat DESC
SQL Fiddle example
You could, but unless you add metadata columns to the output, it will not be of much use.
select NameColumn, CategoryColumn, QuantityColumn, 0 IsCategory
from tbl
union all
select distinct CategoryColumn, CategoryColumn, null, 1
from tbl
order by CategoryColumn, IsCategory desc, NameColumn;
Sure, to get your EXACT output order, you can omit and NULLify certain columns, e.g.
select NameColumn, NULL as CategoryColumn, QuantityColumn
from (
select NameColumn, CategoryColumn, QuantityColumn, 0 IsCategory
from tbl
union all
select distinct CategoryColumn, CategoryColumn, null, 1
from tbl
) X
order by X.CategoryColumn, IsCategory desc, NameColumn;
But if you're intending to use the data outside of SQL Server, you'll want to keep the metadata to relate names and the categories to the original categories they came from. The IsCategory will also be useful to identify the headers that were picked out of the CategoryColumn.

SQL Server NULLS: duplicate last known value in table

I need some advice.
I have a column with nulls in a field at a particular time period.
Name Date
----- -----
Cat 1/1/2012
Dog 1/2/2012
Fish 1/3/2012
NULL 1/4/2012
Goat 1/5/2012
NULL 1/6/2012
Sheep 1/7/2012
In the example above, how would I write a SQL statement to select the last known value for column Name whenever there is a null value in the column?
For instance I'd like the table to look like this:
Name Date
----- -----
Cat 1/1/2012
Dog 1/2/2012
Fish 1/3/2012
Fish 1/4/2012
Goat 1/5/2012
Goat 1/6/2012
Sheep 1/7/2012
Would this pseudo-code work?
Select
isnull(Name, "Select Name from Table where Date = GetDate() - 1")
,Date
From Table
Try this [v is original, v2 is calculated new value] :
DECLARE #table table(v varchar(10), d varchar(10))
INSERT INTO #table
SELECT 'Cat','1/1/2012' UNION
SELECT 'Dog','1/2/2012' UNION
SELECT 'Fish','1/3/2012' UNION
SELECT NULL,'1/4/2012' UNION
SELECT 'Goat','1/5/2012' UNION
SELECT NULL,'1/6/2012' UNION
SELECT 'Sheep','1/7/2012'
SELECT A.v, A.d, ISNULL(A.v,B.v) V2
FROM #table A
OUTER APPLY ( SELECT TOP 1 *
FROM #table
WHERE d < A.d
AND v IS NOT NULL
ORDER BY d desc) B
order by d

Resources