I am using TSQL.
If I have the following results:
And I want to transpose this to be like this:
How can I achieve this?
I have the following query:
WITH q AS (
SELECT *
FROM tableOne
WHERE ID = 1
UNION ALL
SELECT m.*
FROM tableOne m
JOIN ON m.ParentID = q.ID
)
SELECT *
FROM q
This gives me all of the items underneath the specified node including the specified node.
It could be easy for us to help you if you add scripting data and not an image. Note that tbl is the name of your table, it is called 3 times. Try this:
select
a.fieldValue company,
b.fieldValue department,
c.fieldValue Job
from tbl a
inner join tbl b on a.parentId is null and a.id=b.parentID
inner join tbl c on b.id= c.parentID
If it does not bring desired results please add data as text and let me know, I could modify the query
Another option (assuming this is NOT a jagged hierarchy).
This is a standard Recursive CTE, with a little twist in the final SELECT
Example
;with cteP as (
Select ID
,ParentID
,PathID = cast(FieldValue as varchar(max))
From YourTable
Where ParentID is Null
Union All
Select ID = r.ID
,ParentID = r.ParentID
,PathID = cast(p.PathID+'|||'+r.FieldValue as varchar(max))
From YourTable r
Join cteP p on r.ParentID = p.ID)
Select ID
,B.*
From cteP A
Cross Apply (
Select Company = xDim.value('/x[1]','varchar(max)')
,Department = xDim.value('/x[2]','varchar(max)')
,Job = xDim.value('/x[3]','varchar(max)')
From (Select Cast('<x>' + replace(PathID,'|||','</x><x>')+'</x>' as xml) as xDim) as X
) B
Where ID not in (Select Distinct ParentID from YourTable where ParentID is not null)
Order By PathID
Returns
I want to get all data from 2 table based on userID=user1
from parent and child table as i shown in below image
I think this should work:
SELECT parent.CommentID as CommentID,
parent.userID as userID,
parent.Message as Message,
parent.Date as date,
NULL as ParentCommentID
FROM #ParentComment parent
WHERE UserID = 'user1'
UNION
SELECT child.c_commentID as CommentID,
child.c_userID as userID,
child.c_message as Message,
child.c_Date as date,
child.c_parentcommentID as ParentCommentID
FROM #ChildComment child
WHERE child.c_userID = 'user1'
Here's an SQL fiddle : http://sqlfiddle.com/#!9/3bb46/2
Hope this helps!!!
Use Join
Inner join if the id always match
select
a.CommentID as CommentI
,a.userID, as userID
, a.Message as Message
, a.Date as date
, b.c_commentID as parent__comment_id
from parent_comment as a
inner join child_comment as b on a.commentID = b.c_commentID
left join if not always match
select
a.CommentID as CommentI
,a.userID, as userID
, a.Message as Message
, a.Date as date
, b.c_commentID as parent__comment_id
from parent_comment as a
left join child_comment as b on a.commentID = b.c_commentID
Just use Left join with union like this example
Select TP.*
FROM ParentTable as TP LEFT JOIN ChildTable as TC
ON TC.c_ParentcommentID = TP.commentID AND TC.c_ParentcommentID = null
WHERE TP.userID='user1'
UNION ALL
Select TC.c_CommnetID as CommentID , TC.c_userID as userID , TC.c_Message as Message , TC.Date as 'Date'
FROM ChildTable as TC inner join ParentTable as TP
ON TC.c_ParentcommentID = TP.commentID
WHERE TC.userID='user1'
I'm not a DBA so please don't yell at me. Trying to do an inner join and Group By using a concatenated column. The ON statement is producing a syntax error. I do not have access to the original tables and am trying to normalize this into another table, I know its ugly. Not overly worried about performance, just need to work. Cant use functions either.
SELECT DISTINCT A.[carrier_code],[carrier_name], [carrier_grouping], A.[collector_name], [dataset_loaded], [docnum], [envoy_payer_id], [loc], [market], [master_payor_grouping], [plan_class], [plan_name], A.[resp_ins],A.[resp_ind], A.[resp_payor_grouping], A.[Resp_Plan_Type], A.[rspphone], A.[state], A.[sys],A.[resp_ins]+A.[resp_payor_grouping]+A.[carrier_code]+A.[state]+A.[Collector_Name] as ExtId
FROM [Table1] A
INNER JOIN
(SELECT [resp_ins]+[resp_payor_grouping]+[carrier_code]+[state]+[Collector_Name] as Extid
FROM [Table1]
WHERE [resp_ind] = 'Insurance'
GROUP BY [resp_ins]+[resp_payor_grouping]+[carrier_code]+[state]+[Collector_Name]) B
ON A.[resp_ins]+A.[resp_payor_grouping]+A.[carrier_code]+A.[state]+A.[Collector_Name] = B.[resp_ins]+B.[resp_payor_grouping]+B.[carrier_code]+B.[state]+B.[Collector_Name];
My ON and Group By statements are eventually the primary key in new table.
Your alias B hasn't columns as you mentioned. It has just on column Extid.
SELECT DISTINCT A.[carrier_code],[carrier_name], [carrier_grouping], A.[collector_name], [dataset_loaded], [docnum], [envoy_payer_id], [loc], [market], [master_payor_grouping], [plan_class], [plan_name], A.[resp_ins],A.[resp_ind], A.[resp_payor_grouping], A.[Resp_Plan_Type], A.[rspphone], A.[state], A.[sys],A.[resp_ins]+A.[resp_payor_grouping]+A.[carrier_code]+A.[state]+A.[Collector_Name] as ExtId
FROM [Table1] A
INNER JOIN
(SELECT [resp_ins]+[resp_payor_grouping]+[carrier_code]+[state]+[Collector_Name] as Extid
FROM [Table1]
WHERE [resp_ind] = 'Insurance'
GROUP BY [resp_ins]+[resp_payor_grouping]+[carrier_code]+[state]+[Collector_Name]) B
ON A.[resp_ins]+A.[resp_payor_grouping]+A.[carrier_code]+A.[state]+A.[Collector_Name] = B.Extid;
Try this, I didn't put all the column in result, you can manage yourself.
select A.*
from
(
select [carrier_code],[carrier_name], [sys],[resp_ins]+[resp_payor_grouping]+[carrier_code]+[state]+[Collector_Name] as ExtId
FROM [Table1]
) A
inner join
(
select distinct Extid
from
(
SELECT [resp_ins]+[resp_payor_grouping]+[carrier_code]+[state]+[Collector_Name] as ExtId
FROM [Table1]
WHERE [resp_ind] = 'Insurance'
) ins
) B on (A.ExtId = B.ExtId)
You don't need to concatenate the values - you can GROUP BY and JOIN on multiple columns.
SELECT DISTINCT
...
FROM
[Table1] A
INNER JOIN
(
SELECT
[resp_ins],
[resp_payor_grouping],
[carrier_code],
[state],
[Collector_Name]
FROM
[Table1]
WHERE
[resp_ind] = 'Insurance'
GROUP BY
[resp_ins],
[resp_payor_grouping],
[carrier_code],
[state],
[Collector_Name]
) B
ON
(
A.[resp_ins] = B.[resp_ins]
Or
(A.[resp_ins] Is Null And B.[resp_ins] Is Null)
)
And
(
A.[resp_payor_grouping] = B.[resp_payor_grouping]
Or
(A.[resp_payor_grouping] Is Null And B.[resp_payor_grouping] Is Null)
)
And
(
A.[carrier_code] = B.[carrier_code]
Or
(A.[carrier_code] Is Null And B.[carrier_code] Is Null)
)
And
(
A.[state] = B.[state]
Or
(A.[state] Is Null And B.[state] Is Null)
)
And
(
A.[Collector_Name] = B.[Collector_Name]
Or
(A.[Collector_Name] Is Null And B.[Collector_Name] Is Null)
)
;
the first query:
SELECT u.id , prop1.id
FROM ( SELECT '9fbc6e9b59504c08ac643752c1e2d033' AS id ,
'|6813dbbfec6241a19b8d2316d2cb2a65,1|' AS customprop
UNION
SELECT 'f2271c45682f45fc84527c4afff0ab16' AS id ,
'|6813dbbfec6241a19b8d2316d2cb2a65,2|' AS customprop
) u
INNER JOIN ( SELECT ROW_NUMBER() OVER ( ORDER BY a.Id ) id ,
A.Id propId ,
B.NAME
FROM ( SELECT '6813dbbfec6241a19b8d2316d2cb2a65' AS id ,
CONVERT(XML, '<v>1,职业资格1</v><v>2,职业资格2</v>') AS value
) A
OUTER APPLY ( SELECT Name = N.v.value('.',
'nvarchar(Max)')
FROM A.[VALUE].nodes('/v') N ( v )
) B
) prop1 ON CHARINDEX('|' + prop1.propid + ','
+ CONVERT(NVARCHAR(10), prop1.id)
+ '|', u.customprop) > 0
GROUP BY u.id ,
prop1.id
the second query:
SELECT u.id ,prop1.id, count(*)
FROM ( SELECT '9fbc6e9b59504c08ac643752c1e2d033' AS id ,
'|6813dbbfec6241a19b8d2316d2cb2a65,1|' AS customprop
UNION
SELECT 'f2271c45682f45fc84527c4afff0ab16' AS id ,
'|6813dbbfec6241a19b8d2316d2cb2a65,2|' AS customprop
) u
INNER JOIN ( SELECT ROW_NUMBER() OVER ( ORDER BY a.Id ) id ,
A.Id propId ,
B.NAME
FROM ( SELECT '6813dbbfec6241a19b8d2316d2cb2a65' AS id ,
CONVERT(XML, '<v>1,职业资格1</v><v>2,职业资格2</v>') AS value
) A
OUTER APPLY ( SELECT Name = N.v.value('.',
'nvarchar(Max)')
FROM A.[VALUE].nodes('/v') N ( v )
) B
) prop1 ON CHARINDEX('|' + prop1.propid + ','
+ CONVERT(NVARCHAR(10), prop1.id)
+ '|', u.customprop) > 0
GROUP BY u.id ,
prop1.id
sql can be executed on sqlserver 2005 directly.
the first query can produce one item and the second query produce two items.
I think that the two queries should both produce two items.
I have thouht for three days and I really want to konw why.
I'm a Chinese and my English is poor.I hope you can understand my description
Tough question, but the problem is with this line:
INNER JOIN ( SELECT ROW_NUMBER() OVER ( ORDER BY a.Id ) id ,
The ORDER BY is ambiguous and consequently, if it is executed multiple times (which it can be because of the INNER JOIN it is contained in), it may not always return the same ordering/assignment. This can cause a latter join condition to only match on one record instead of two, which is what happens in the query plan being used for the version without the count(*) column.
To fix this, you just need to add something to make the ordering assignment unique, like this:
INNER JOIN ( SELECT ROW_NUMBER() OVER ( ORDER BY a.Id, B.Name ASC ) id ,
Try it like this, it should work.
Your problem is with the ORDER BY clause of the ROW_NUMBER - since the a.ID is not unique the outcome is unpredictable. Make that unique and your problem will go away - you can use something like
...SELECT ROW_NUMBER() OVER ( ORDER BY newid() ) id...
I just want to know that How to write a CTE containing If Exists in SQl Server ?
I had tried to write a CTE below where i am Using If Exists Statement to select weather the record exist or not .In case if the record does not exist then i am assigning default value but i am getting error
'Incorrect syntax near the keyword 'if'
.' Please help me to fix this error and guide me to write this CTE.
Please find below the CTE which i had written:-
Alter procedure St_Proc_GetTeamProductionReport
#mindate DateTime,
#maxdate DateTIme,
#userID varchar(50)
as
Begin
set NoCount on;
with
ProductionCTE(CalendarDate,RoleID,UserID,UserECode,UserName,ImmediateSupervisor,NatureOfWorkName,RegionProjectName,CountyName,WorkTypeName,TaskName,VolumneProcessed,TimeSpent,Comment)
as
(
if exists
(
select P.CalendarDate,U.RoleID,U.UserID,U.UserECode,U.UserName,U.ImmediateSupervisor,N.NatureofWorkName,
R.RegionProjectName,C.Countyname,W.WorktypeName,T.TaskName,P.VolumeProcessed,P.Timespent,P.Comment
from production P inner join NatureOfWork N
on N.NatureofWorkID=P.natureofworkid
inner join dbo.RegionAndProjectInfo R
on R.RegionProjectID=P.RegionProjectID
inner join county C
on C.countyid=P.countyid
inner join worktype W
on W.Worktypeid=P.worktypeID
inner join task T
on T.taskid=P.TaskID
inner join UserInfo U
on U.Userid=P.userid
where P.userid=#userID and ( convert(varchar, P.CalendarDate, 101) ) between (
convert(varchar, #mindate, 101) ) and ( convert(varchar, #maxdate, 101) )
)
else
(
Select '2012-09-14 13:41:52' as CalendarDate,
2 as RoleID,'938' as UserID,
(select Userecode from Userinfo where userid=#userID) as UserECode,
(select UserName from Userinfo where userid=#userID)as UserName,
(select ImmediateSupervisor from Userinfo where userid=#userID)as ImmediateSupervisor,
'BP' as NatureOfWorkName,
'CO Processing' as RegionProjectName,
'Adams' as CountyName,
'Quality' as WorkTypeName,
'Corrections ' as TaskName,
5 as VolumneProcessed,
'01:00' as TimeSpent,
'test' as Comment
)
union all
select P.CalendarDate,U.RoleID,U.UserID,U.UserECode,U.UserName,U.ImmediateSupervisor,N.NatureofWorkName,
R.RegionProjectName,C.Countyname,W.WorktypeName,T.TaskName,P.VolumeProcessed,P.Timespent,P.Comment
from production P inner join NatureOfWork N
on N.NatureofWorkID=P.natureofworkid
inner join dbo.RegionAndProjectInfo R
on R.RegionProjectID=P.RegionProjectID
inner join county C
on C.countyid=P.countyid
inner join worktype W
on W.Worktypeid=P.worktypeID
inner join task T
on T.taskid=P.TaskID
inner join UserInfo U
on U.Userid=P.userid
inner join ProductionCTE
on U.ImmediateSupervisor=ProductionCTE.UserECode
where P.IsTaskCompleted=1 and ( convert(varchar, P.CalendarDate, 101) ) between (
convert(varchar, #mindate, 101) ) and ( convert(varchar, #maxdate, 101) )
)
select distinct CONVERT(VARCHAR,CalendarDate,20) as CalendarDate,UserECode,UserName,NatureOfWorkName,RegionProjectName,CountyName,WorkTypeName,TaskName,VolumneProcessed,TimeSpent,Comment from ProductionCTE where RoleID=1
end
GO
When i am removing this If Exist statement then the CTE is working fine but after adding the IF Exists statement it is having error.
You can't use IF EXISTS in this way. A common table expression must only contain a single select statement, it's not possible to say if condition SELECT THIS else SELECT THAT.
It looks like you are trying to add an additional created row to a resultset returned by a query. You could achieve this by implementing the CTE as a table-valued function that would return the single new row.
http://msdn.microsoft.com/en-gb/library/ms191165(v=sql.105).aspx
If you want to construct a UNION where you only get a result from the second SELECT if the first SELECT returns no rows, you can achieve this using RANK(). So, you can place your real query in the first SELECT and the desired default values in the second, and achieve the results you want.
I don't have your tables and data, so I'm not going to attempt to re-write your query. But I'll illustrate with this:
;With WithDefaults as (
select name,0 as Rank from sys.objects
union all
select 'abc',1 --Default if no results
), Ranked as (
select *,RANK() OVER (ORDER BY Rank) as Rnk from WithDefaults
)
select * from Ranked where Rnk = 1
Returns (on a mostly empty DB I tried it on) 98 results, of which none had the name abc. If we force the first SELECT to return no results:
select name,0 as Rank from sys.objects where 1 = 2
We now get a single row result with the name abc.
Hopefully, you can see how this could apply to your original query.
You can't use IF EXISTS in CTE. But you can modify logic of function
Example:
alter procedure St_Proc_GetTeamProductionReport
#mindate DateTime,
#maxdate DateTIme,
#userID varchar(50)
as
Begin
set NoCount on;
;with
ProductionCTE(CalendarDate,RoleID,UserID,UserECode,UserName,ImmediateSupervisor,NatureOfWorkName,RegionProjectName,CountyName,WorkTypeName,TaskName,VolumneProcessed,TimeSpent,Comment)
as
(
select P.CalendarDate,U.RoleID,U.UserID,U.UserECode,U.UserName,U.ImmediateSupervisor,N.NatureofWorkName,
R.RegionProjectName,C.Countyname,W.WorktypeName,T.TaskName,P.VolumeProcessed,P.Timespent,P.Comment, 1 AS cnt
from production P inner join NatureOfWork N
on N.NatureofWorkID=P.natureofworkid
inner join dbo.RegionAndProjectInfo R
on R.RegionProjectID=P.RegionProjectID
inner join county C
on C.countyid=P.countyid
inner join worktype W
on W.Worktypeid=P.worktypeID
inner join task T
on T.taskid=P.TaskID
inner join UserInfo U
on U.Userid=P.userid
where P.userid=#userID and ( convert(varchar, P.CalendarDate, 101) ) between (
convert(varchar, #mindate, 101) ) and ( convert(varchar, #maxdate, 101) )
UNION ALL
Select '2012-09-14 13:41:52' as CalendarDate,
2 as RoleID,'938' as UserID,
(select Userecode from Userinfo where userid=#userID) as UserECode,
(select UserName from Userinfo where userid=#userID)as UserName,
(select ImmediateSupervisor from Userinfo where userid=#userID)as ImmediateSupervisor,
'BP' as NatureOfWorkName,
'CO Processing' as RegionProjectName,
'Adams' as CountyName,
'Quality' as WorkTypeName,
'Corrections ' as TaskName,
5 as VolumneProcessed,
'01:00' as TimeSpent,
'test' as Comment, 0
), ProductionCTE2 AS
(
SELECT TOP(SELECT CASE WHEN COUNT(*) = 0 THEN 1 ELSE COUNT(*) END FROM ProductionCTE WHERE cnt = 1)
CalendarDate,RoleID,UserID,UserECode,UserName,ImmediateSupervisor,NatureofWorkName,
RegionProjectName,Countyname,WorktypeName,TaskName,VolumeProcessed,Timespent,Comment
FROM ProductionCTE2
union all
select P.CalendarDate,U.RoleID,U.UserID,U.UserECode,U.UserName,U.ImmediateSupervisor,N.NatureofWorkName,
R.RegionProjectName,C.Countyname,W.WorktypeName,T.TaskName,P.VolumeProcessed,P.Timespent,P.Comment
from production P inner join NatureOfWork N
on N.NatureofWorkID=P.natureofworkid
inner join dbo.RegionAndProjectInfo R
on R.RegionProjectID=P.RegionProjectID
inner join county C
on C.countyid=P.countyid
inner join worktype W
on W.Worktypeid=P.worktypeID
inner join task T
on T.taskid=P.TaskID
inner join UserInfo U
on U.Userid=P.userid
inner join ProductionCTE
on U.ImmediateSupervisor=ProductionCTE.UserECode
where P.IsTaskCompleted=1 and ( convert(varchar, P.CalendarDate, 101) ) between (
convert(varchar, #mindate, 101) ) and ( convert(varchar, #maxdate, 101) )
)
select distinct CONVERT(VARCHAR,CalendarDate,20) as CalendarDate,UserECode,UserName,NatureOfWorkName,RegionProjectName,CountyName,WorkTypeName,TaskName,VolumneProcessed,TimeSpent,Comment
from ProductionCTE2
where RoleID=1
end