Is there an alternative for XML PATH in SQL - sql

I am developing a clinic management application.
In that application there is a part where doctors choose what they use up in each service they provide.
For example, when a doctor examines a patient, a pair of gloves and wooden stick are used and disposed of.
I use a trick that is simply, I create a string in the service table, that string has the IDs separated with comma (something like that 1,3,7,) and it works fine except for one case.
That case is when I want to display the used up item names as one column for multiple services.
I get items of service one plus service two and so on as one string for all service.
Is there any way I can solve that?
I know it sounds complicated but If it works it will many other you read this.
The way I use to join is:
on CHARINDEX(CAST(TblSupply.IDSupply as varchar(10)), TblService.UsedSupplyIDs) > 0
Simply I cast the Used Item ID TblSupply.IDSupply as string then check if it exists in the service table.
When I display as separate columns, it works fine but I get multiple rows for the same service as follows:
Select
TblService.ServiceName,
TblSupply.SupplyName
from
TblService
left join TblSupply on CHARINDEX(CAST(TblSupply.IDSupply as varchar(10)), TblService.UsedSupplyIDs) > 0
e.g.
_____________________________________________
|TblService.ServiceName|TblSupply.SupplyName |
|Patient examination |Glove |
|Patient examination |wood stick |
|Patient examination |thermometer |
|Sonar examination |Glove |
|Sonar examination |lubricating Gel |
|Consultation |Glove |
|______________________|_____________________|
I want to get
________________________________________________________
|TblService.ServiceName|xxxxx |
|Patient examination |Glove ,wood stick , thermometer |
|Sonar examination |Glove,lubricating Gel |
|Consultation |Glove |
The code I made
Select
TblService.ServiceName,TempTable.SupplyList
from
TblService
left join (Select TblService.IDService As IDService,
STUFF((Select ', ' + TblSupply.SupplyName
FROM
TblService
left join TblSupply on CHARINDEX(CAST(TblSupply.IDSupply as varchar(10)), TblService.UsedSupplyIDs) > 0
FOR XML PATH('')), 1, 1, '') as SupplyList
FROM
TblService
GROUP BY
TblService.IDService
) as TempTable on TempTable.IDService=TblService.IDService
I tried
Select
TblPatientService.IDPatientService,
TblService.ServiceName,
TempTable.SupplyList
from
TblPatientService
left Join TblService On TblService.IDService = TblPatientService.IDService
left join (Select TblPatientService.IDPatientService As IDPatientService
STUFF((Select ', ' + TblSupply.SupplyName
FROM
TblPatientService
left join TblService on TblService.IDService = TblPatientService.IDService
left join TblSupply on CHARINDEX(CAST(TblSupply.IDSupply as varchar(10)), TblService.UsedSupplyIDs) > 0
WHERE
TblPatientService.IDService = TblService.IDService
FOR XML PATH('')), 1, 1, '') as SupplyList
FROM
TblPatientService
left Join TblService On TblService.IDService = TblPatientService.IDService
GROUP BY
TblPatientService.IDPatientService
) as TempTable on TempTable.IDPatientService = TblPatientService.IDPatientService
What I really get
|TblService.ServiceName|xxxxx
|Patient examination |Glove ,wood stick , thermometer,Glove,lubricating Gel,Glove,lubricating Gel |
|Sonar examination |Glove ,wood stick , thermometer,Glove,lubricating Gel,Glove,lubricating Gel |
|Consultation |Glove ,wood stick , thermometer,Glove,lubricating Gel,Glove,lubricating Gel |
In other words I get all the used items for all services as if they used for one service for all displayed.

Since SQL Server 2017, you can use STRING_AGG. Somtehing like :
SELECT TblPatientService.IDPatientService AS IDPatientService,
STRING_AGG(TblSupply.SupplyName, ', ') AS SupplyList
FROM TblPatientService
LEFT OUTER JOIN TblService ON TblService.IDService = TblPatientService.IDService
LEFT OUTER JOIN TblSupply ON CHARINDEX(CAST(TblSupply.IDSupply AS VARCHAR(10)), TblService.UsedSupplyIDs) > 0
GROUP BY TblPatientService.IDPatientService;
To replace XML stuff !

This is too long for a comment.
I would strongly suggest fixing your data model. Storing delimited lists in database columns is a typical design antipattern, that will backfire in different ways (complexity, efficiency, maintenance, data integrity). You can ha have a look at this famous SO question for more details.
As an exemple: your current join condition will not do what you expect for some supply ids that are more than one digit long (typically, 1 would match 10).
You should normalize your model and have a separate table to store the N-M relationship between services and supplies, with one tuple per row.

Related

SQL join two tables by modifying on columns

I have 3 tables on PostgreSQL:
SPENDINGS:
store |spending
-----------+---------
0000700551 | $75
STORE:
store | zip_code
-------+---------
700551 | XXP PDD
CUSTOMER:
id | zip_code
----+----------
002 | XXPPDD
I would love to join these tables like this:
right(SPENDIGNS.store, 6) = STORE.store and
trim(STORE.zip_code) = CUSTOMER.zip_code.
How can I do that could you help me out please?
trim(store.zip_code) is not good for the job because the whitespace is within the zip code text. Use replace(store.zip_code, ' ', '') instead. right(spendings.store, 6) does not seem safe to me too. Better use ltrim(spendings.store, '0') to remove leading zeroes. SQL Fiddle
select *
from spendings sp
join store st on ltrim(sp.store, '0') = st.store
join customer cu on cu.zip_code = replace(st.zip_code, ' ', '');
BTW your data design does need improvement.
try something as follows (you can use what ever join you would like to in place of inner)
select spendings.spending, store.store,customer.zipcode
from spendings inner join store on right(SPENDIGNS.store, 6) = STORE.store
inner join customer on trim(STORE.zip_code) = CUSTOMER.zip_code

Merging multiple rows of data into same column

I would like to create a table of job ids and a column listing all the different job categories that get matched up, but concatenated into the same column. As an example, right now job 82041 has two categories, but now is returning two rows. I would like for it to say "Retail, Sales Associate", all in one field.
The code that I tried is below, can anybody tell me what I am doing wrong?
EXAMPLE:
jobOrderID (No column name)
82027 Motion Graphics
82029 Other
82030 Product Designer
82041 Retail
82041 Sales Associate
82069 Social Media
EXAMPLE CODE:
select JobOrder.jobOrderID ,
stuff((select distinct ', ' + cast(Category.occupation as nchar(30))
from Category
where Category.categoryID = JobOrderCategories.categoryID
for xml path ('')),1,1,'')
from JobOrder
left outer join JobOrderCategories
on JobOrder.joborderid = JobOrderCategories.jobOrderID
left outer join Category
on Category.categoryID = JobOrderCategories.categoryID
where JobOrder.dateAdded > '2017-5-2' and JobOrder.dateAdded < '2017-5-3'
and joborder.isDeleted = 0
order by joborder.dateAdded asc
Figured it out by altering the left joins
select
JobOrder.jobOrderID,
stuff((select distinct ', ' + cast(Category.occupation as varchar(30))
from Category
left outer join JobOrderCategories on (Category.categoryID = JobOrderCategories.categoryID and joborder.jobOrderID = JobOrderCategories.joborderid)
where Category.categoryID = JobOrderCategories.categoryID
for xml path ('')),1,1,'')
from JobOrder
where JobOrder.dateAdded > '2017-5-2' and JobOrder.dateAdded < '2017-5-3'
and joborder.isDeleted = 0

Handle Complex Query

I have following tables with their columns
tbAgent :- Agent, AgentX, AgentCode, NIPRNumber, PhysicalAddressState,
SystemUser
tbBroker :- Broker, BusinessName, BrokerCode,SystemUser
tbCompany :- Company, CompanyX
tbSystemUser :- SystemUser FirstName, LastName, EmailAddress
tbProduct :- Product, ProductX, ProductCode, Jurisdiction, CompanyId
tbLicence :- Licence, LicenceNumber,DateIssued,ExpirationDate,Jurisdiction,
StateIssued, BrokerId, AgentId
tbCompanyAgent :- CompanyId, AgentId, ProductId, LicenseNumber,
LicenseIssueDate,LicenceExpirationDate
tbBrokerAgent :- BrokerId, AgentId
tbJurisdiction :- Jurisdiction, JurisdictionX
In this project, we store Agents, Agencies (Brokers) and Companies in tbAgent, tbBroker and tbCompany respectively. We store Company's Products in tbProduct.
Thr Agent's LicenseDetails are stored in tbLicence. Agent's are appointed to Agencies(Brokers) and these details are stored in tbBrokerAgent.
Also Agents are appointed to Companies and these details are stored in tbCompanyAgent. The Agents are appointed to Companies, if Company's product's Jurisdiction matched with the Agent's License's Resident State or Non Resident state.
Note that Agent's has two type of licences stored in tbLicence, one is Resident and other is Non Resident Licenses. If it is Resident License, then the column name "Jurisdiction" contains 0 and If it is Non Resident License, then it contain actual Jurisdiction Id of State. If it contains 0 then we have to consider Agent's PhysicalAddressState as ResidentState.
All jurisdictions (States) are present in tbJurisdiction.
Now I have to create a view where I have to fetch the following Information
CompanyX
CompanyCode
BrokerX
BrokerCode
AgentX
Agentcode
NIPRNumber
ProductX
ProductCode
State
LicenceNumber
EffectiveDate
ExpirationDate
I have tried the following query
SELECT a.AgentCode,sy.AgentName,L.Licence,L.LicenceNumber,DateIssued as EffectiveDate,L.ExpirationDate,J.JurisdictionX as State
From tbAgent as a
INNER JOIN tbLicence L ON L.AgentId=a.Agent
LEFT OUTER JOIN (SELECT Jurisdiction,JurisdictionX FROM tbJurisdiction) as j on j.Jurisdiction=
(
CASE WHEN ISNULL(L.Jurisdiction,'0')='0' THEN a.PhysicalAddressState
ELSE
L.Jurisdiction
END
)
LEFT OUTER JOIN (SELECT SystemUser, (FirstName + ' '+LastName) as AgentName FROM tbSystemUser ) as sy on sy.SystemUser=a.SystemUser
The above query is fetching the following information
AgentX
Agentcode
NIPRNumber
State
LicenceNumber
EffectiveDate
ExpirationDate
Excluding the following columns
CompanyX
CompanyCode
BrokerX
BrokerCode
ProductX
ProductCode
I am not able to tweak the above query for fetching the excluding Column's information because the query is getting complex to handle...
Please help me !!!
If the question is about complexity, I hope CTE-technique will be a good tip for you:
;WITH cteJur as
(
SELECT
Jurisdiction,
JurisdictionX
FROM tbJurisdiction j
),
cteSysUsr as
(
SELECT
SystemUser,
(FirstName + ' '+LastName) as AgentName
FROM tbSystemUser su
),
cteAgent as
(
SELECT
a.AgentCode, a.SystemUser,
L.Licence, L.LicenceNumber,
L.DateIssued as EffectiveDate, L.ExpirationDate,
CASE
WHEN ISNULL(L.Jurisdiction,'0')='0'
THEN a.PhysicalAddressState
ELSE L.Jurisdiction
END as Jurisdiction
FROM tbAgent as a
INNER JOIN tbLicence L ON L.AgentId=a.Agent
)
SELECT
a.AgentCode, sy.AgentName,
a.Licence, a.LicenceNumber,
a.EffectiveDate, a.ExpirationDate,
J.JurisdictionX as State
FROM tbAgent as a
LEFT JOIN cteJur as j on j.Jurisdiction = a.Jurisdiction
LEFT JOIN cteSysUsr as sy on sy.SystemUser = a.SystemUser
If you were looking where to include your "excluded columns" - add them into appropriate CTE and reference them in final select. You don't have to put every joined table into a subquery. Just join it and reference table's columns in select list, that's it. Just as described in the query above.
First, you appear to have a good following of the tables and how related. I have tried to implement them and get ALL columns from the respective table(s). You can strip out whatever you want.
Now, first, I want you to look at the FROM clause section. Think of this before getting the columns, especially in a complex query of a lot of tables being joined. Take each one to the next. I always try to do my joins with the first table (or alias) as the left-side of the ON clause and the JOINING TO as the right-side... Then, if something is nested under the second, I keep the indentation going so I see the literal correlations more directly and have less chance of getting confused.
from
FirstTable alias1
JOIN SecondTable alias2
on alias1.IDColumn = alias2.IDColumn
JOIN ThirdTable alias3
on alias2.OtherID = alias3.OtherID
Now, in the case of your Jurisdictions, there are 3 possible places it CAN originate from... The agent, product and the license. Because I do not know which version you specifically want, I applied LEFT-JOINs to each one respectively. This allows me to use the same table multiple times with different aliases. Then I grab each JurisdictionX and call it an appropriate "as" name in the result.
Finally, I build out all the field columns that are wanted. If you wanted to narrow the list of data (such as a single broker) then you just apply the WHERE criteria. Hopefully this makes a lot of sense and you can strip out the extra fields you may not care about.
SELECT
a.Agent,
a.AgentX,
a.AgentCode,
a.NIPRNumber,
a.PhysicalAddressState,
a.SystemUser,
( AgUser.FirstName + ' '+ AgUser.LastName) as AgentName,
AgUser.EmailAddress as AgentEMail,
b.Broker,
b.BusinessName,
b.BrokerCode,
b.SystemUser as BrokerUser,
( BrUser.FirstName + ' '+ BrUser.LastName) as BrokerName,
BrUser.EmailAddress as BrokerEMail,
l.License,
l.LicenseNumber,
l.DateIssued,
l.ExpirationDate,
l.Jurisdiction,
l.StateIssued,
ca.LicenseNumber as CA_LicenseNumber,
ca.LicenseIssueDate as LicenseIssueDate,
ca.LicenseExpirationDate as LicenseExpirationDate,
c.Company,
c.CompanyX,
p.ProductX,
p.ProductCode,
AgJuris.JurisdictionX as AgentJurisdiction,
LicJuris.Jurisdiction as LicenseJurisdiction,
ProdJuris.Jurisdiction as ProductJurisdiction
from
tbAgent a
JOIN tbSystemUser AgUser
ON a.SystemUser = ag.SystemUser
JOIN tbLicense l
ON a.Agent = l.AgentID
JOIN tbBroker B
ON l.BrokerID = B.BrokerID
JOIN tbSystemUser BrUser
ON b.SystemUser = br.SystemUser
LEFT JOIN tbJurisdiction LicJuris
ON ISNULL(L.Jurisdiction,'0') = LicJuris.Jurisdiction
JOIN tbCompanyAgent ca
ON a.Agent = ca.AgentID
JOIN tbCompany c
ON ca.CompanyID = c.Company
JOIN tbProduct p
ON ca.CompanyID = p.CompanyID
AND ca.ProductID = p.Product
LEFT JOIN tbJurisdiction ProdJuris
ON p.Jurisdiction = ProdJuris.Jurisdiction
LEFT JOIN tbJurisdiction AgJuris
ON a.PhysicalAddressState = AgJuris.Jurisdiction
Additionally, for the issue on Jurisdictions, since you have all 3 POSSIBLE, you could add a last column such as
COALESCE( LicJuris.Jurisdiction, AgJuris.JurisdictionX ) as WhichJurisdiction
or considering all 3...
COALESCE( LicJuris.Jurisdiction, COALESCE( ProdJuris.Jurisdiction , AgJuris.JurisdictionX )) as WhichJurisdiction
So, if the license jurisdiction is not available, grab the value from product jurisdiction, if not that, fall back to the agent's jurisdiction.

Merge multiple rows in data to show only a single row in the result

I have a stored procedure which takes 1 parameter, an ID number (systudentid).
The procedure returns 3 rows: a student’s academic counselor (AC), financial counselor (FC), and admissions counselor (EC) along with relevant contact information; 3 different people.
Certain students have ACs and FCs who are the same person, but the query will still return 3 rows.
AdvisorType|AdvisorLastName|AdvisorFirstName|(other data)|systaffID
AC DOE JOHN ..... 12345
AC DOE JOHN ..... 12345
EC SMITH JANE ..... 45678
Where in my code can I plug in the logic (and how, I'm a newbie with sql) so that when the systudentid passed to the procedure identifies a student having the same person for both AC and FC, it will display the results this way.
The advisor type is changed to "SSA" and only one of the records for the double-duty counselor is returned.
AdvisorType|AdvisorLastName|AdvisorFirstName|(other data)|SystaffID
SSA DOE JOHN ...... 12345
EC SMITH JANE ...... 45678
Here is my select statement:
SELECT
SyStaffGroup.Descrip AS AdvisorType
,SyStaff.LastName AS AdvisorLastName
,SyStaff.FirstName AS AdvisorFirstName
,SyStaff.Phone AS AdvisorPhone
,SyStaff.Ext AS AdvisorExtention
,SyStaff.eMail AS AdvisorEMail
,SyStaff.SyStaffID AS SyStaffID
FROM SyStaff (NOLOCK)
JOIN SyAdvisorByEnroll (NOLOCK)
ON SyAdvisorByEnroll.SyStaffID = SyStaff.SyStaffID
JOIN SyStaffGroup (NOLOCK)
ON SyStaffGroup.SyStaffGroupID = SyAdvisorByEnroll.SyStaffGroupID
JOIN AdEnroll (NOLOCK)
ON AdEnroll.AdEnrollID = SyAdvisorByEnroll.AdEnrollID
JOIN SyStudent (NOLOCK)
ON AdEnroll.SyStudentID = SyStudent.SyStudentId
WHERE
SyStaff.Active = 1
--AND
--syadvisorbyenroll.adenrollid = (
--SELECT adenrollid from dbo.fn_student_enrollment_activeenrollmentlist (#systudentid)
--)
AND adEnroll.adEnrollID IN (
SELECT adEnrollID FROM dbo.fn_Student_Enrollment_ActiveEnrollmentList(#SyStudentID)
)
AND SyAdvisorByEnroll.AdvisorModule IN ('AD','FA')
AND SyStaffGroup.Descrip IN ('AC - Academic Counselor', 'FC - Finance Counselors', 'EC - Adm. Counselor With Reg')
UNION
SELECT DISTINCT
'Admissions Counselor' AS AdvisorType
,SyStaff.LastName AS AdvisorLastName
,SyStaff.FirstName AS AdvisorFirstName
,SyStaff.Phone AS AdvisorPhone
,SyStaff.Ext AS AdvisorExtention
,SyStaff.eMail AS AdvisorEMail
,SyStaff.SyStaffID AS SyStaffID
FROM systudent
INNER JOIN AmRep ON SyStudent.AMREpID = AmREp.AMREpid
INNER JOIN SyStaff ON SyStaff.SyStaffID = AmRep.AmRepID
WHERE Systudent.SYStudentid = #systudentid
Any hints or suggested methods that I can either try or Google (I've tried searching but results are a lot more useful if I knew what to look for) would be greatly appreciated.
You can add a nested subquery to indicate which students have the same advisor filling multiple positions, and adjust the type selection accordingly. Here are the changed portions of your above query:
SELECT
CASE WHEN (mutiples.SyStaffID IS NOT NULL) THEN 'SSA'
ELSE SyStaffGroup.Descrip END AS AdvisorType
-- other columns omitted
FROM SyStaff (NOLOCK)
JOIN SyAdvisorByEnroll (NOLOCK)
ON SyAdvisorByEnroll.SyStaffID = SyStaff.SyStaffID
LEFT JOIN (
SELECT SyStaffID,AdEnrollID
FROM SyAdvisorByEnroll
GROUP BY SyStaffID,AdEnrollID
HAVING COUNT(DISTINCT SyStaffGroupID) > 1
) multiples
ON multiples.SyStaffID = SyAdvisorByEnroll.SyStaffID
AND multiples.AdEnrollID = SyAdvisorByEnroll.AdEnrollID
-- rest of query omitted
This might have a mistake or two, since you didn't include your table schema. The nested subquery, "multiples", contains all advisor / enrollee pairs where the advisor is in multiple groups. You left join against this and adjust the final type selection to "SSA" if there's a matching entry in the nested subquery.
An important note: as written, this will include two SSA rows for an eligible advisor / enrollee pair. However, the final results will not, because you are using a UNION in this query, which filters out duplicates, even if they're only present in one half of the union. If you change this to UNION ALL or eliminate the UNION entirely, you will need to add DISTINCT to the top of the query, like so:
SELECT DISTINCT CASE WHEN (mutiples.SyStaffID IS NOT NULL) ...

Query TFS database to fetch last 10 check-in details

Is there a way to query TFS database to get the last 10 check-in details
The output should be something like
File name | Comment | Changed By | Date
----------------------------------------------------------------------------
Test.cs Added new functionality username 01/08/2010
I am aware that the above result set can be obtained using TFS SDK. But I want to know if
there is a way to query the TFS database to fetch the above data.
Thanks
If I understand your question correctly, this will get you most of the way there in SQL:
SELECT TOP 10
V.ChildItem AS [File name],
CS.Comment,
I.DisplayName AS [Changed By],
CS.CreationDate AS [Date]
FROM tbl_Changeset CS
INNER JOIN tbl_Identity I ON I.IdentityID = CS.OwnerID
INNER JOIN tbl_Version V ON V.VersionFrom = CS.ChangesetID
ORDER BY CS.CreationDate DESC
There are some escaped characters in the file names that showed up while I was testing this on my TFS instance (like underscore characters become ">"). Other than that this should serve you well.
A lot of these queries are no longer relevant with newer instances of TFS. One of the big reasons is that the user identities (tbl_Identity) have been moved. Tfs_DefaultCollection is the DB that stored all information pertinent to a given Collection, but TFS can host multiple Collections AND an Admin can change the name of the default Collection when they are setting up TFS.
As such, all user identities have been moved to the Tfs_Configuration database;
select * from [tfs_Configuration].dbo.tbl_Identity
Gaining Access to the descriptive part of the account name ( AccountName or DisplayName ) from a Collection DB is accomplished by Join from [tfs_DefaultCollection].dbo.tbl_IdentityMap
select *
from [tfs_Configuration].dbo.tbl_Identity I
JOIN [tfs_DefaultCollection].dbo.tbl_IdentityMap IM
ON I.Id = IM.MasterID
With this information in hand, we can now produce the following query to show the last 100 ChangeSets committed to TFS as well as the name of the committer.
select top 100 *
from tbl_changeset as c
JOIN tbl_IdentityMap IM
ON C.OwnerID = IM.localId
JOIN tfs_configuration.dbo.tbl_Identity u
ON IM.MasterID = u.Id
Order by C.ChangeSetID DESC
Looking at this data, we can see A LOT of IDs, Sids, Lookups, etc. What we will NOT see in this data is any information about the File that was committed or information about the Branch the Commit was made to. This information comes from the tbl_Version table.
select top 100 *
from [tfs_DefaultCollection].dbo.tbl_changeset as c
JOIN [tfs_DefaultCollection].dbo.tbl_IdentityMap IM
ON C.OwnerID = IM.localId
JOIN [tfs_configuration].dbo.tbl_Identity u
ON IM.MasterID = u.Id
JOIN [tfs_DefaultCollection].dbo.tbl_Version as v
ON v.Versionfrom = c.ChangeSetId
Order by C.ChangeSetID DESC
[tfs_DefaultCollection].dbo.tbl_Version has a few columns of interest, namely; ParentPath, ChildItem & FullPath. What is missing here is any useful information regarding the Branch that the commit was made to. Branch info is embedded in either of the 2 available Path fields;
$\da3da7cf"80b5"4385"b3dc"ebb3088f3c01\Features\Inpatient\Source\Yadda\Yadda\Yadda\
This begs the next question, where is Branch info stored in TFS? Thanks to StackOverflowUsers answer above, this information was found in [tfs_DefaultCollection].dbo.TreeNodes table;
select * from [tfs_DefaultCollection].dbo.[TreeNodes] where parentID=0 and fDeleted=0
The Column CssNodeID is the ID we are looking for to make sense out of the FullPath
CoolBranchName da3da7cf-80b5-4385-b3dc-ebb3088f3c01
However, this presents us with our next challenge regarding the TFS Databases. A lot of information is encoded and\or embedded so we need to manipulate a few things to get what we are after.
In this instance, the part of the [tfs_DefaultCollection].dbo.tbl_Version.ParentPath or [tfs_DefaultCollection].dbo.tbl_Version.FullPath value that contains the Branch info.
This ugly little diddy right here extracts the ID portion of the ParentPath field value and replaces all the Double-Quotes with Hyphens which gives us an Id value we can use to query [Tfs_DefaultCollection].dbo.TreeNodes
SUBSTRING(
REPLACE( v.ParentPath, '$\', ''),
CHARINDEX( '\', REPLACE( v.ParentPath, '$\', '') ),
( LEN( v.ParentPath ) - CHARINDEX( '\', REPLACE( v.ParentPath, '$\', '') ) )
)
Putting all of this together in pursuit of a Query to Fetch The Last [X] Check-In details results in the following;
select top 10
c.CreationDate,
c.Comment,
u.DisplayName as CommittingUser,
TN.Name as BranchName,
SUBSTRING(
REPLACE( v.ParentPath, '$\', ''),
CHARINDEX( '\', REPLACE( v.ParentPath, '$\', '') ),
( LEN( v.ParentPath ) - CHARINDEX( '\', REPLACE( v.ParentPath, '$\', '') ) )
) as ChangedFile
from tbl_changeset as c
JOIN tbl_IdentityMap IM
ON C.OwnerID = IM.localId
JOIN [Tfs_Configuration].dbo.tbl_Identity u
ON IM.MasterID = u.Id
JOIN dbo.tbl_Version as v
ON v.Versionfrom = c.ChangeSetId
LEFT JOIN dbo.TreeNodes TN with(nolock)
ON TN.CssNodeId = REPLACE(
SUBSTRING(
REPLACE( v.ParentPath, '$\', ''),
0,
CHARINDEX( '\', REPLACE( v.ParentPath, '$\', '') )
),
'"', '-'
)
AND parentID=0
AND fDeleted=0
Order by c.CreationDate desc
Note that I included the DB qualifiers for all the queries leading up to the final query to provide context on where tables of interest are located.
As a workaround how about the below query.. But i think it is returning me the wrong comments.. not sure why.
SELECT top 10
C.ChangeSetId,
V.FullPath,
V.ParentPath,
REPLACE(V.ChildItem,'\','') as [FileName],
C.CreationDate,
I.DisplayName,
C.Comment
FROM tbl_Version(nolock) V
INNER JOIN tbl_File (nolock) F ON V.ItemId = F.ItemId
INNER JOIN tbl_Changeset (nolock) C ON V.VersionTo = C.ChangeSetId
INNER JOIN tbl_Identity (nolock) I ON C.CommitterId = I.IdentityId
where v.ParentPath like '$\' + (select name from [TfsWorkItemTracking].[dbo].[treenodes] where parentid=0 and fdeleted=0 and id=524) + '\%'
order by C.CreationDate desc
Thanks to mark.crockett for posting the above query # http://social.msdn.microsoft.com/Forums/en-US/tfsreporting/thread/32d2c27e-825b-43bb-b156-36048a3e70cb/
If you have access to the SQL server that hosts TFS database the db you have to look is TFSWarehouse, then you can look for the tables Work Item,tbl_Changeset,tbl_Identity,tbl_Version etc. from where you can pull some information.
Thnks.