Get the TFS 2015 Work Item Hierarchy in SQL Server - sql

I'm trying to create a report in Tableau to generate a tree structure of all the work items in TFS 2015 and their respective hierarchy
Such as
Epic->Features->User Story->Task
But repeated attempts to create the sql query have failed. Could you please help me with the SQL query that could help fetch all the work items and display their hierarchy?
Thanks.

Instead of using SQL Query, it's suggested to use TFS REST API to create a query in TFS, the WIQL looks like:
"wiql": "select [System.Id], [System.WorkItemType], [System.Title], [System.AssignedTo], [System.State], [System.Tags] from WorkItemLinks where (Source.[System.TeamProject] = 'xxx' and Source.[System.WorkItemType] <> '' and Source.[System.State] <> '') and ([System.Links.LinkType] = 'System.LinkTypes.Hierarchy-Forward') and (Target.[System.WorkItemType] <> '') order by [System.Id] mode (Recursive)"

So, i have found this query, which is working and can help you create a tableau workbook for the hierarchy:
WITH cte
AS ( SELECT DimTeamProject.ProjectNodeName ,
System_WorkItemType ,
DimWorkItem.System_Id ,
FactWorkItemLinkHistory.TargetWorkItemID ,
DimWorkItem.System_Title,
DimWorkItem.System_State,
DimWorkItem.Microsoft_VSTS_Common_ActivatedDate,
DimWorkItem.Microsoft_VSTS_Scheduling_TargetDate,
DimWorkItem.System_CreatedDate,
DimWorkItemLinkType.LinkName,
TeamProjectSK,
system_rev,
row_number() over( partition by system_id,TeamProjectSK, FactWorkItemLinkHistory.TargetWorkItemID order by system_rev desc ) rownum
FROM DimWorkItem ,
DimTeamProject ,
FactWorkItemLinkHistory,
DimWorkItemLinkType
WHERE DimWorkItem.TeamProjectSK = DimTeamProject.ProjectNodeSK
AND DimWorkItem.System_Id = FactWorkItemLinkHistory.SourceWorkItemID
and DimWorkItemLinkType.WorkItemLinkTypeSK = FactWorkItemLinkHistory.WorkItemLinkTypeSK
/* -To Test the Query using the project Name of our choice- */
--AND ProjectNodeName =
AND System_State in ('ACTIVE','NEW')
/* -System Revisions are created when the entry is modified. Onlt the latest entry will have the below revised date- */
AND System_RevisedDate = '9999-01-01 00:00:00.000'
AND DimWorkItemLinkType.Linkname IN ( 'Parent',
'child' )
GROUP BY DimTeamProject.ProjectNodeName ,
DimWorkItem.System_Id ,
FactWorkItemLinkHistory.TargetWorkItemID ,
DimWorkItem.System_Title ,
System_WorkItemType,
DimWorkItem.System_State,
TeamProjectSK,
DimWorkItemLinkType.LINKName,
DimWorkItem.Microsoft_VSTS_Common_ActivatedDate,
DimWorkItem.Microsoft_VSTS_Scheduling_TargetDate,
DimWorkItem.System_CreatedDate,
system_rev
)
SELECT distinct t1.ProjectNodeName ,
t1.System_Id requirement_Id ,
t1.System_WorkItemType,
t1.System_Title requirement_title ,
t2.System_Id Change_request_id ,
t1.LinkName,
t2.System_Title Change_Request_Title,
t1.Microsoft_VSTS_Common_ActivatedDate,
t1.System_CreatedDate,
t1.Microsoft_VSTS_Scheduling_TargetDate,
t1.System_State,
T1.rownum
FROM cte t1
INNER JOIN cte t2 ON t1.TargetWorkItemID = t2.System_Id
and t1.rownum = 1
ORDER BY t1.System_Id;
Used a CTE to find get the complete hierarchy, its faster and more efficient than the query posted before.

Related

Update failing while using dense_rank and row_number

Here is the sample data of the two tables , just put together for easy reference
I want the upper part of the table [Outbound].[dbo].[Encounter_Out_P] with column "277CA_FILENAME","277CA_FILENAME2","277CA_FILENAME3","277CA_FILENAME4" as NULLS which are sorted by File_Submitted_DT ascending order to be updated with "277FileId" values of the lower table [Outbound].[dbo].[Encounter_Out_277_P] which are sorted by EDIFECSProcessDate in ascending order. Thanks in advance
Here is my code
WITH
cte_2771 AS (
SELECT
"277CA_FILENAME",
File_Submitted_DT,
TRN02_PatientControlNumber
FROM (
SELECT
I."277CA_FILENAME",
I.File_Submitted_DT,
#cte_277.TRN02_PatientControlNumber
,dense_rank() OVER(PARTITION BY #cte_277.TRN02_PatientControlNumber ORDER BY ABS(DATEDIFF(MINUTE, i.File_Submitted_DT, #cte_277.EDIFECSProcessDate)) ASC) rw1
FROM
[Outbound].[dbo].[Encounter_Out_P] I
INNER JOIN #cte_277 ON I.EncounterID = #cte_277.TRN02_PatientControlNumber
--WHERE EncounterID = 'AP230120920712808806'
)t
WHERE
t.rw1 = 1
)
,
cte_2772 AS (
SELECT
"277FileId"
,1 + ((ROW_NUMBER() OVER(PARTITION BY TRN02_PatientControlNumber ORDER BY EDIFECSProcessDate,File_Submitted_DT ASC ) - 1) % 4)rw2
,TRN02_PatientControlNumber
FROM (
SELECT DISTINCT
p."277FileId",
p.EDIFECSProcessDate,
p.TRN02_PatientControlNumber
,p.ID
,cte_2771.File_Submitted_DT
FROM [Outbound].[dbo].[Encounter_Out_277_P] p
INNER JOIN cte_2771 ON cte_2771.File_Submitted_DT < p.EDIFECSProcessDate
WHERE
p.TRN02_PatientControlNumber = cte_2771.TRN02_PatientControlNumber
) t
)
UPDATE cte_2771
SET "277CA_FILENAME" =
COALESCE(cte_2771."277CA_FILENAME", cte_2772."277FileId" )
FROM cte_2771 INNER JOIN cte_2772
ON cte_2772.TRN02_PatientControlNumber = cte_2771.TRN02_PatientControlNumber
WHERE cte_2772.rw2 = 1
I want the output to be like below, (the upperpart) just put together for easy reference
Notes
I have posted the code for "277CA_FILENAME" only, since it is the same for the rest by changing the WHERE condition changes as "WHERE cte_2772.rw2 = 2,3,4"
if I Uncomment the --WHERE EncounterID = 'AP230120920712808806' in the cte_2771 , it is working perfectly, but if I comment it and run for the entire load, one row gets correct and the other one gets NULL

Formatting the code from IT to match Power Query / Power BI

Could someone please confirm what code language is it and how do I edit it to fit with Power BI function to import data from SQL Database please?
Got this from IT person but when I try to paste it into Power Query it gives error messages.
SELECT distinct Z.Territory , (z.AccountNumber ) as AccountNumber , (a.AccountType ) as AccountType , (z.CompanyName ) as CompanyName , (z.AccountNumber ) as AccountNumber , (z.CompanyName ) as CompanyName , z.SubscriptionReference ,z.SubscriptionID , (isnull(z.serialnumber,r.SerialNumber) ) as SerialNumber ,case when (rpc.billingperiodalignment) = 'AlignToCharge' then (z.product) else isnull(r.ProductDescription,z.product) end as Description , (r.ProductVersion ) as ProductVersion , (r.CoverExpiryDate ) as CoverExpiryDate , (z.SubscriptionStatus ) as SubscriptionStatus ,z.SubscriptionVersion
--, MAX(z.RenewalTerm) AS RenewalTerm , (z.[SubscriptionTermType]) as [SubscriptionTermType] , (case when z.[UnitofMeasure] = 'Desktop Users' then z.[Quantity] end) as 'Desktop Users' , (z.billingperiod ) as BillingPeriod ,(rpc.BillingPeriodAlignment) BillingPeriodAlignment ,(z.[ContractEffectiveDate]) as ContractEffectiveDate ,(z.TermEndDate) as TermEndDate
It's SQL, but it's invalid, so you'll need to get it fixed. It looks like it got cut off. When it's valid you should be able to paste it into a SQL Server Management Studio query window and test it.
To use it in Power Query use Value.NativeQuery, like this;
let
Source = Sql.Database("localhost", "adventureworks2017"),
Query = "
select *
from Sales.SalesOrderHeader
",
Data = Value.NativeQuery(Source, Query, null, [EnableFolding=true])
in
Data

single query two opposite group by

I'm trying to generate report based off of SQL Queries. I need to generate one report with Source = "Web" and other without Source <> "Web". I've read multiple posts on this but none of them gave me the answer. Query below.
SELECT
content_provider,
provider_asset_id,
device_id,
carrier,
T.profile_id,
phonenumber,
dma,
CAST( asset_play_duration as decimal(15, 3) ) AS asset_play_duration,
series_title,
episode_title,
source,
vsession_id AS session_id,
event_day
FROM
(SELECT
device_id,
program_asset_id,
vsession_id,
source,
vsession_start_ts,
batchtime,
vsession_end_ts,
IF ( studio = '', network_tag, studio ) AS content_provider,
provider_asset_id,
carrier,
profile_id,
phonenumber,
series_title,
episode_title,
content_type,
dma,
asset_play_duration,
source,
event_day,
ROW_NUMBER() OVER (PARTITION BY device_id, program_asset_id, vsession_id, vsession_start_ts ORDER BY batchtime DESC) AS rank
FROM ? ) T
LEFT JOIN ? tp
ON T.profile_id = tp.profile_id
WHERE tp.profile_id IS NULL
AND T.rank = 1
**AND T.source <> "Web"**
AND T.event_day BETWEEN ? AND ?
One report should be with above condition (T.Source <>"web") and other should be without the filter (T.Source = "Web"). I tried Union and Inner join, and both of them did not work. Any help is appreaciated.
Pass yet another variable for whether you want to select "Web" or not, filled accordingly with 'YES' or 'NO'. Then:
AND ((? = 'YES' AND T.source = "Web") OR T.source <> "Web")
This assumes there is a column named "Web" (which you could call Web without quotes anyway). If Web is supposed to be a string, on the other hand, you'd use single quotes: 'Web'.

Use of MAX function in SQL query to filter data

The code below joins two tables and I need to extract only the latest date per account, though it holds multiple accounts and history records. I wanted to use the MAX function, but not sure how to incorporate it for this case. I am using My SQL server.
Appreciate any help !
select
PROP.FileName,PROP.InsName, PROP.Status,
PROP.FileTime, PROP.SubmissionNo, PROP.PolNo,
PROP.EffDate,PROP.ExpDate, PROP.Region,
PROP.Underwriter, PROP_DATA.Data , PROP_DATA.Label
from
Property.dbo.PROP
inner join
Property.dbo.PROP_DATA on Property.dbo.PROP.FileID = Actuarial.dbo.PROP_DATA.FileID
where
(PROP_DATA.Label in ('Occupancy' , 'OccupancyTIV'))
and (PROP.EffDate >= '42278' and PROP.EffDate <= '42643')
and (PROP.Status = 'Bound')
and (Prop.FileTime = Max(Prop.FileTime))
order by
PROP.EffDate DESC
Assuming your DBMS supports windowing functions and the with clause, a max windowing function would work:
with all_data as (
select
PROP.FileName,PROP.InsName, PROP.Status,
PROP.FileTime, PROP.SubmissionNo, PROP.PolNo,
PROP.EffDate,PROP.ExpDate, PROP.Region,
PROP.Underwriter, PROP_DATA.Data , PROP_DATA.Label,
max (PROP.EffDate) over (partition by PROP.PolNo) as max_date
from Actuarial.dbo.PROP
inner join Actuarial.dbo.PROP_DATA
on Actuarial.dbo.PROP.FileID = Actuarial.dbo.PROP_DATA.FileID
where (PROP_DATA.Label in ('Occupancy' , 'OccupancyTIV'))
and (PROP.EffDate >= '42278' and PROP.EffDate <= '42643')
and (PROP.Status = 'Bound')
and (Prop.FileTime = Max(Prop.FileTime))
)
select
FileName, InsName, Status, FileTime, SubmissionNo,
PolNo, EffDate, ExpDate, Region, UnderWriter, Data, Label
from all_data
where EffDate = max_date
ORDER BY EffDate DESC
This also presupposes than any given account would not have two records on the same EffDate. If that's the case, and there is no other objective means to determine the latest account, you could also use row_numer to pick a somewhat arbitrary record in the case of a tie.
Using straight SQL, you can use a self-join in a subquery in your where clause to eliminate values smaller than the max, or smaller than the top n largest, and so on. Just set the number in <= 1 to the number of top values you want per group.
Something like the following might do the trick, for example:
select
p.FileName
, p.InsName
, p.Status
, p.FileTime
, p.SubmissionNo
, p.PolNo
, p.EffDate
, p.ExpDate
, p.Region
, p.Underwriter
, pd.Data
, pd.Label
from Actuarial.dbo.PROP p
inner join Actuarial.dbo.PROP_DATA pd
on p.FileID = pd.FileID
where (
select count(*)
from Actuarial.dbo.PROP p2
where p2.FileID = p.FileID
and p2.EffDate <= p.EffDate
) <= 1
and (
pd.Label in ('Occupancy' , 'OccupancyTIV')
and p.Status = 'Bound'
)
ORDER BY p.EffDate DESC
Have a look at this stackoverflow question for a full working example.
Not tested
with temp1 as
(
select foo
from bar
whre xy = MAX(xy)
)
select PROP.FileName,PROP.InsName, PROP.Status,
PROP.FileTime, PROP.SubmissionNo, PROP.PolNo,
PROP.EffDate,PROP.ExpDate, PROP.Region,
PROP.Underwriter, PROP_DATA.Data , PROP_DATA.Label
from Actuarial.dbo.PROP
inner join temp1 t
on Actuarial.dbo.PROP.FileID = t.dbo.PROP_DATA.FileID
ORDER BY PROP.EffDate DESC

Determine if last action performed on each item was an install or a removal

I'm attempting to normalize a work database, currently one of the table has roughly 120 columns, and I'm building a new table that will correct many of the issues.
I'm attempting to figure out how to write a query that finds out which Panels are still installed.
Among the fields in the table, some of the most relevant are:
ActualCompleteDate
PanelID
WorkType ("electrical install", "electrical removal")
I need to write a query that can isolate all installed Panels, and allow me to get their ID so I can use that query to migrate all necessary data to a new table. There are 12 other columns that need to be moved to the new table.
EDIT
The complete query based off of FuzzyTree's solution below:
SELECT CHSRNumber,CableSize,CableLength,[CEA Type],CHSRLoc
,PanelID,ConnectorType,BreakerAmps,Voltage,[Status]
,InstallRDCLoc,Phase,UPS,BreakerType,ActualCompleteDate
FROM (
SELECT CHSRNumber,CableSize,CableLength,[CEA Type],CHSRLoc
,PanelID,ConnectorType,BreakerAmps,Voltage,[Status]
,InstallRDCLoc,Phase,UPS,BreakerType,WorkType,[ActualCompleteDate]
,row_number() OVER (
PARTITION BY PanelID
ORDER BY ActualCompleteDate DESC
) rn
FROM [Facilities_Database].[Facilities].[HardwareSupportRequest] t1
) t1
WHERE rn = 1 AND [WorkType] LIKE '%electric install%'
--AND (CableLength IS NOT NULL
-- OR [CEA Type] IS NOT NULL
-- OR [CableSize] IS NOT NULL)
ORDER BY CHSRNumber
This will select all PanelIDs that have been installed and have not been removed after installation
select PanelID from (
select PanelID,
row_number() over (partition by PanelID order by ActualCompleteDate desc) rn,
WorkType
from mytable
) t1 where rn = 1 and WorkType = "electrical install"
or using not exists if your db doesn't support row_number()
select PanelID from mytable t1
where WorkType = "electrical install"
and not exists (
select 1 from mytable t2
where t2.PanelID = t1.PanelID
and t2.ActualCompleteDate > t1.ActualCompleteDate
and t2.WorkType = "electrical removal"
)
another method, a little easier to debug/extend:
select i.* from
(select
PanelID,
max(ActualCompleteDate) as max_datei
from
table
where
worktype = "electrical install"
group by
PanelID) i left outer join
(select
PanelID,
max(ActualCompleteDate) as max_dater
from
table
where
worktype = "electrical removal"
group by
PanelID) r on
i.panelid = r.panelid and
maxdatei > maxdater or
maxdater is null