ordering a self-referencing table by DFS search in sql - sql

I have a self refrenced table that represents some data like below:
declare #table table(
ID int,
ParentID int,
Name varchar(50),
levelNode int
)
declare #Temptable table(
ID int,
ParentID int,
Name varchar(50),
levelNode int
)
declare #maxlevel int
insert into #table (ID,ParentID,Name,levelNode) select 11,null,'A',1
insert into #table (ID,ParentID,Name,levelNode) select 12,11,'B-1',2
insert into #table (ID,ParentID,Name,levelNode) select 13,11,'B-2',2
insert into #table (ID,ParentID,Name,levelNode) select 14,12,'B-1-1',3
insert into #table (ID,ParentID,Name,levelNode) select 15,12,'B-1-2',3
insert into #table (ID,ParentID,Name,levelNode) select 16,12,'B-1-3',3
insert into #table (ID,ParentID,Name,levelNode) select 17,13,'B-2-1',3
insert into #table (ID,ParentID,Name,levelNode) select 18,13,'B-2-2',3
insert into #table (ID,ParentID,Name,levelNode) select 19,13,'B-2-3',3
insert into #table (ID,ParentID,Name,levelNode) select 20,19,'B-2-3-1',4
insert into #table (ID,ParentID,Name,levelNode) select 21,19,'B-2-3-2',4
insert into #table (ID,ParentID,Name,levelNode) select 22,17,'B-2-1-1',4
insert into #table (ID,ParentID,Name,levelNode) select 23,17,'B-2-1-2',4
declare #ID int
select #ID=11;
With ret AS(
select * from #table
where ID=#ID
union all
select t.* from #table t inner join ret r ON t.ParentID=r.ID
)
insert into #Temptable select * from ret where ID<>#ID
order by ??????????????????
select * from #Temptable
I want to order them like this:
What should I write in order by section!

Try this..
Fiddle demo
INSERT INTO #Temptable
SELECT *
FROM ret
WHERE id <> #ID
ORDER BY Substring(NAME, 3, 1),
Substring(NAME, 5, 1),
Substring(NAME, 7, 1)

Related

sql query for counting the records of particular id and show in column

I have a following table:-
declare #tab table(name varchar(10),id int)
insert into #tab values ('A',1),('B',1),('C',1),('D',1),('E',2),('F',2)
I need following output:-
declare #tab1 table(name varchar(10),id int, cnt int)
insert into #tab1 values ('A',1,4),('B',1,4),('C',1,4),('D',1,4),('E',2,2),('F',2,2)
select * from #tab1
I tried following query:-
select name,id,count(*) as cnt
from #tab
group by name,id
Thanks
Try this
select name
, id
, count(*) over(partition by id) as cnt
from #tab
;
Done
;with a as
(
select Id,name, count(*) over (partition by id) cnt
from #tab
)
select Id,name,cnt
from a

How to select from string array added in SQL column?

Below is my table,
create table t(
id int,
colParam varchar(max))
insert into t values(1,'["param1", "param2"]')
insert into t values(2,'["param2"]')
insert into t values(3,'["param1"]')
insert into t values(4,'["param2", "param3"]')
insert into t values(5,'["param1", "param2"]')
tried
declare #str varchar(max) = 'param1'; Select * from t where colParam like '%'+ #str+'%'
its not working for
declare #str varchar(max) = 'param1,param2'; Select * from t where colParam like '%'+ #str+'%'
i want to select rows by passing colPar as 'param1,param2' so it will result me all the records containing param1 and param2 in colParam
This quiet tricky.
create table #t(
id int,
colParam varchar(max)
)
insert into #t values(1,'["param1", "param2"]')
insert into #t values(2,'["param2"]')
insert into #t values(3,'["param1"]')
insert into #t values(4,'["param2", "param3"]')
insert into #t values(5,'["param1", "param2"]')
declare #str varchar(max) = 'param1,param2';
to Return all matching values.
select distinct id, t1.colParam from #t t1
cross apply string_split(t1.colParam, ',') t2
cross apply string_split(#str, ',') t3
where t2.value like '%'+t3.value+'%'
Output:
If you are using SQL Server 2016 and above, then you can use STRING_SPLIT.
As MSDN says:
A table-valued function that splits a string into rows of substrings,
based on a specified separator character.
So your can look like this:
DECLARE #t TABLE
(
id int,
colParam varchar(max)
)
insert into #t values(1,'["param1", "param2"]')
insert into #t values(2,'["param2"]')
insert into #t values(3,'["param1"]')
insert into #t values(4,'["param2", "param3"]')
insert into #t values(5,'["param1", "param2"]')
SELECT
t.id
, s.col
FROM #t AS t
OUTER APPLY
(
SELECT
spl.value AS col
FROM STRING_SPLIT(
(SELECT _t.colParam FROM #t AS _t WHERE _t.id = t.id), ',') AS spl
)s

Sum of last 6 rows for same day as today in SQL Server

I need to calculate sum of past six rows for same day for given id.
Have a look at the sample data and result expected..
create table #t (id int, a datetime, dy varchar(10), t int);
insert into #t values
(1,'2017-01-03','Tuesday',7),
(1,'2017-01-10','Tuesday',5),
(1,'2017-01-17','Tuesday',5),
(1,'2017-01-24','Tuesday',2),
(1,'2017-01-31','Tuesday',6),
(1,'2017-02-07','Tuesday',4),
(1,'2017-02-14','Tuesday',5),
(1,'2017-02-21','Monday',2),
(1,'2017-02-28','Monday',4),
(1,'2017-03-07','Monday',4),
(1,'2017-03-17','Monday',4),
(1,'2017-03-21','Monday',4);
(1,'2017-03-2','Monday',4);
create table #t_result (id int, a datetime, dy varchar(10),t int);
insert into #t_result values
(1,'2017-01-03','Tuesday',29),
(1,'2017-02-14','Monday',22)
select * from #t
select * from #t_result
Thanks in advance
You can do some window function manipulation and output every 6th row (modulo operator on ROW_NUMBER).
SELECT
id, a, [sum]
FROM
(
SELECT
id
, FIRST_VALUE( a ) OVER (ORDER BY a ROWS 5 PRECEDING) AS a
, SUM( t ) OVER (ORDER BY a ROWS 5 PRECEDING) AS [sum]
, ROW_NUMBER() OVER (ORDER BY a) AS rownum
FROM
#t
) AS data
WHERE
rownum % 6 = 0
--Try Using While Loop
BEGIN TRAN
CREATE TABLE #t (id INT, a DATETIME ,dy VARCHAR(10), t INT);
CREATE TABLE #t_result (id INT, a DATETIME,dy VARCHAR(10),t INT);
CREATE TABLE #Temp (id INT, a DATETIME, t INT, dy VARCHAR(10),temp_count INT);
INSERT INTO #T VALUES
(1,'2017-01-03','Thursday',7),
(1,'2017-01-10','Thursday',5),
(1,'2017-01-17','Thursday',5),
(1,'2017-01-24','Thursday',2),
(1,'2017-01-31','Thursday',6),
(1,'2017-02-07','Thursday',4),
(1,'2017-02-14','Thursday',5),
(1,'2017-02-21','Monday',2),
(1,'2017-02-28','Monday',4),
(1,'2017-03-07','Monday',4),
(1,'2017-03-17','Monday',4),
(1,'2017-03-21','Monday',4),
(1,'2017-03-2' ,'Monday',4)
DECLARE #Strt INT,#End INT
SELECT *, ROW_NUMBER()OVER(ORDER BY ID)rownum INTO #Temp_data FROM #t
SET #Strt=1
SELECT #End= MAX(rownum) FROM #Temp_data
WHILE #Strt<= #End BEGIN
DECLARE #Id INT , #T INT , #Date DATETIME, #total INT, #count INT, #Temp_count INT, #D DATETIME, #Dy VARCHAR(10)
SELECT #Id= Id, #T=t, #Dy=dy, #Date= a FROM #Temp_data WHERE rownum= #Strt
INSERT INTO #Temp
SELECT #Id, #Date, #T, #Dy,1
SELECT #Temp_count= COUNT(*) FROM #Temp
IF #Temp_count=6 BEGIN
SELECT *,ROW_NUMBER()OVER(Order by ID)rownum INTO #tt FROM #Temp
SELECT #D=a FROM #tt WHERE rownum=1
INSERT INTO #t_result
SELECT ID, #D,dy,SUM(t)
FROM #Temp
WHERE DATEPART(yyyy, a) = YEAR(DATEADD(year,-1,GETDATE()))AND dy = DATENAME(DW,GETDATE())
GROUP BY id,dy
HAVING COUNT(*)=6
DELETE FROM #Temp
DROP TABLE #tt
END
SET #Strt= #Strt +1
END
SELECT * FROM #t_result
ROLLBACK TRAN
Try this:
SELECT MIN(D.id)Id,MIN(D.a)a,D.dy,SUM(D.t)T
FROM(
select *,ROW_NUMBER() OVER(PARTITION BY id,dy ORDER BY a)RN
from #t
)D
WHERE D.RN<=6
GROUP BY D.dy
ORDER BY a
OutPut:
Id a dy T
1 2017-01-03 00:00:00.000 Tuesday 29
1 2017-02-21 00:00:00.000 Monday 22

How to insert keyvalue as a row in table?

I have table variable which contains records in terms of key,value pair of a table. where key is the column of table and value is the value for that column
below is table variable
DECLARE #Table TABLE(
FieldName varchar(100),
FieldValue varchar(max))
insert into #Table values('Title','NewFrom')
insert into #Table values('Points','4')
insert into #Table values('createdby','5')
I have above values in UsersInformation.This is physical table of sql server
has following column.
UserID int autoincrement(identity)
Title nvarchar(100),
Points int,
createdby int
I want that all values of #Table should be as a single row of UserInformation table.
How can be using sql server?
Have not tested but this should work
INSERT INTO UsersInformation (Title, Points, createdby)
SELECT Title, Points, createdby FROM (SELECT FieldName, FieldValue
FROM #Table) AS SourceTable
PIVOT (MAX(FieldValue) FOR FieldName IN ([Points], [Title], [createdby])) AS PivotTable;
Based on your comment you will need to add a key to your source #table
DECLARE #Table TABLE(
id int,
FieldName varchar(100),
FieldValue varchar(max))
insert into #Table values(1,'Title','NewFrom')
insert into #Table values(1,'Points','4')
insert into #Table values(1,'createdby','5')
insert into #Table values(2,'Title','NewFrom2')
insert into #Table values(2,'Points','44')
insert into #Table values(2,'createdby','55')
insert into #Table values(3,'Title','NewFrom3')
insert into #Table values(3,'Points','444')
Then you can run the query:
SELECT [Title], [Points], [createdby]
FROM #Table
PIVOT
(
max(FieldValue) FOR [FieldName] IN ([Title], [Points], [createdby])
) AS P

CTE to build hierarchy from source table

I am trying to build a CTE or just some query that takes hierarchial data from one table and insert it into another table that might have a different index. I thought this would be simple, but for some reason I'm getting stuck. I can't get the output to read correctly on the 'RequiredID' with the newly seeded index. Btw I'm working in SQL Server 2012.
Below I've provided proof of concept code to demonstrate what I'm going for. The actual SQL is more complex, but this illustrates the point.
This is what I've got so far:
DECLARE #Table TABLE (ID INT, Code NVARCHAR(50), RequiredID INT);
INSERT INTO #Table (ID, Code, RequiredID) VALUES
(1, 'Physics', NULL),
(2, 'Advanced Physics', 1),
(3, 'Nuke', 2),
(4, 'Health', NULL);
DECLARE #DefaultSeed TABLE (ID INT, Code NVARCHAR(50), RequiredID INT);
WITH hierarchy
AS (
--anchor
SELECT t.ID , t.Code , t.RequiredID
FROM #Table AS t
WHERE t.RequiredID IS NULL
UNION ALL
--recursive
SELECT t.ID
, t.Code
, h.ID
FROM hierarchy AS h
JOIN #Table AS t
ON t.RequiredID = h.ID
)
INSERT INTO #DefaultSeed (ID, Code, RequiredID)
SELECT ID
, Code
, RequiredID
FROM hierarchy
OPTION (MAXRECURSION 10)
DECLARE #NewSeed TABLE (ID INT IDENTITY(10, 1), Code NVARCHAR(50), RequiredID INT)
--this is where I get stuck - I can't get the requiredID to read like below
INSERT INTO #NewSeed (Code, RequiredID)
SELECT Code, RequiredID
FROM #DefaultSeed
--I'm trying to get #NewSeed should read like the following...
[ID] [Code] [RequiredID]
10....Physics..........NULL
11....Health...........NULL
12....AdvancedPhysics..10
13....Nuke.............12
SELECT *
FROM #NewSeed
Any help would be greatly appreciated!
You can use OUTPUT in combination with Merge to get a Mapping from ID's to new ID's.
The essential part:
--this is where you got stuck
Declare #MapIds Table (aOldID int,aNewID int)
;MERGE INTO #NewSeed AS TargetTable
Using #DefaultSeed as Source on 1=0
WHEN NOT MATCHED then
Insert (Code,RequiredID)
Values
(Source.Code,Source.RequiredID)
OUTPUT Source.ID ,inserted.ID into #MapIds;
Update #NewSeed Set RequiredID=aNewID
from #MapIds
Where RequiredID=aOldID
and the whole example:
DECLARE #Table TABLE (ID INT, Code NVARCHAR(50), RequiredID INT);
INSERT INTO #Table (ID, Code, RequiredID) VALUES
(1, 'Physics', NULL),
(2, 'Advanced Physics', 1),
(3, 'Nuke', 2),
(4, 'Health', NULL);
DECLARE #DefaultSeed TABLE (ID INT, Code NVARCHAR(50), RequiredID INT);
WITH hierarchy
AS (
--anchor
SELECT t.ID , t.Code , t.RequiredID
FROM #Table AS t
WHERE t.RequiredID IS NULL
UNION ALL
--recursive
SELECT t.ID
, t.Code
, h.ID
FROM hierarchy AS h
JOIN #Table AS t
ON t.RequiredID = h.ID
)
INSERT INTO #DefaultSeed (ID, Code, RequiredID)
SELECT ID
, Code
, RequiredID
FROM hierarchy
OPTION (MAXRECURSION 10)
DECLARE #NewSeed TABLE (ID INT IDENTITY(10, 1), Code NVARCHAR(50), RequiredID INT)
Declare #MapIds Table (aOldID int,aNewID int)
;MERGE INTO #NewSeed AS TargetTable
Using #DefaultSeed as Source on 1=0
WHEN NOT MATCHED then
Insert (Code,RequiredID)
Values
(Source.Code,Source.RequiredID)
OUTPUT Source.ID ,inserted.ID into #MapIds;
Update #NewSeed Set RequiredID=aNewID
from #MapIds
Where RequiredID=aOldID
/*
--#NewSeed should read like the following...
[ID] [Code] [RequiredID]
10....Physics..........NULL
11....Health...........NULL
12....AdvancedPhysics..10
13....Nuke.............12
*/
SELECT *
FROM #NewSeed