Related
I have a "flat file" with structure as below:
machineCode,Key,Ip_Name_No,Share_Percent,Account_Name,Account_No
"ygh048GT",4767,534293748,"100.00","cderfgdsc Publishing International Ltd","160102040"
"xcd064HW",6380,65424090,"100.00","dascdfrgh snm skion","00090382478"
"000065AN",6402,65424090,"100.00","xcdertn,john sean","00090382478"
.....
The first row are the column headings. As can be seen, the fields are separated by a comma.
The requirement is to split the single string into separate fields.
This could be done by excel and then uploaded to a DB table using the data to columns option with comma as delimiter but the Account_Name field can contain commas within the values itself.
So, I came up with the below SQL. Question is, does this look correct ? Also, there must be some easier way to do this, any suggestions ?
WITH POS AS (
select
LOCATE_IN_STRING ( DATA , ',' , 2 ) - 1 AS TUNECODE_END ,
LOCATE_IN_STRING (DATA, ',' , LOCATE_IN_STRING ( DATA , ',' , 2 ) + 1) - 1 AS WORKKEY_END,
LOCATE_IN_STRING( DATA , ',' , (LOCATE_IN_STRING (DATA, ',' , LOCATE_IN_STRING ( DATA , ',' , 2 ) + 1) + 1) ) - 1 AS IPNN_END,
LOCATE_IN_STRING( DATA , ',' , (LOCATE_IN_STRING( DATA , ',' , (LOCATE_IN_STRING (DATA, ',' , LOCATE_IN_STRING ( DATA , ',' , 2 ) + 1) + 1) ) + 1) ) - 1 AS PERC_END,
CASE WHEN
SUBSTR ( DATA ,
(
LOCATE_IN_STRING ( DATA , ',' ,
(LOCATE_IN_STRING( DATA , ',' , (LOCATE_IN_STRING( DATA , ',' , (LOCATE_IN_STRING (DATA, ',' , LOCATE_IN_STRING ( DATA , ',' , 2 ) + 1) + 1) ) + 1) ) + 1 ) ) + 1),
1) <> '"'
THEN
LOCATE_IN_STRING ( DATA , ',' ,
(LOCATE_IN_STRING ( DATA , ',' ,
(LOCATE_IN_STRING( DATA , ',' , (LOCATE_IN_STRING( DATA , ',' , (LOCATE_IN_STRING (DATA, ',' , LOCATE_IN_STRING ( DATA , ',' , 2 ) + 1) + 1) ) + 1) ) + 1 ) ) + 1)) - 1
ELSE
LOCATE_IN_STRING ( DATA , ',' ,
(LOCATE_IN_STRING( DATA , ',' , (LOCATE_IN_STRING( DATA , ',' , (LOCATE_IN_STRING (DATA, ',' , LOCATE_IN_STRING ( DATA , ',' , 2 ) + 1) + 1) ) + 1) ) + 1 ) ) - 1
END AS ACNAME_END,
RRN(P) ROWN
FROM PLDWRK P
) SELECT
CAST ( SUBSTR( DATA , 1, TUNECODE_END ) AS CHAR(25))AS MACHINECODE ,
CAST ( SUBSTR( DATA , TUNECODE_END + 2 , WORKKEY_END - (TUNECODE_END + 1) ) AS DEC(12,0)) AS KEY,
CAST(SUBSTR( DATA , WORKKEY_END + 2, IPNN_END - (WORKKEY_END + 1) ) AS DEC(12, 0 )) AS IP_NN,
CAST (SUBSTR( DATA, IPNN_END + 2, PERC_END - (IPNN_END + 1)) AS CHAR(8))AS PERCENTAGE,
CAST (SUBSTR( DATA, PERC_END + 2, ACNAME_END - (PERC_END + 1)) AS CHAR(100)) AS ACCOUNT_NAME,
CAST (SUBSTR( DATA, ACNAME_END + 2 ) AS CHAR(30)) as ACCOUNT_NUMBER
FROM PLDWRK P JOIN POS ON ROWN = RRN(P)
It doesn't work properly for the last row, since one token contains , inside...
select
t.str
, regexp_substr (t.str, '[^,]+', 1, 1) as tok1
, regexp_substr (t.str, '[^,]+', 1, 2) as tok2
---, ...
, regexp_substr (t.str, '[^,]+', 1, 6) as tok6
from
(
values
(1, 'machineCode,Key,Ip_Name_No,Share_Percent,Account_Name,Account_No')
, (2, '"ygh048GT",4767,534293748,"100.00","cderfgdsc Publishing International Ltd","160102040"')
, (3, '"xcd064HW",6380,65424090,"100.00","dascdfrgh snm skion","00090382478"')
, (4, '"000065AN",6402,65424090,"100.00","xcdertn,john sean","00090382478"')
) t (id, str)
order by t.id
STR
TOK1
TOK2
TOK6
machineCode,Key,Ip_Name_No,Share_Percent,Account_Name,Account_No
machineCode
Key
Account_No
"ygh048GT",4767,534293748,"100.00","cderfgdsc Publishing International Ltd","160102040"
"ygh048GT"
4767
"160102040"
"xcd064HW",6380,65424090,"100.00","dascdfrgh snm skion","00090382478"
"xcd064HW"
6380
"00090382478"
"000065AN",6402,65424090,"100.00","xcdertn,john sean","00090382478"
"000065AN"
6402
john sean"
Lots of things are easier than raw SQL...
Why not simply use Copy From Import File (CPYFRMIMPF) that's what it's designed for.
CPYFRMIMPF FROMSTMF('/inbound/somedata.csv') TOFILE(MYLIB/MYTABLE) MBROPT(*REPLACE) RCDDLM(*CRLF) DTAFMT(*DLM) STRDLM(*DBLQUOTE) RMVCOLNAM(*YES)
You'll have to transfer the stream data into the IFS (where it really belongs) instead of a DB table.
IBM's Access Client Solutions (ACS) includes data transfer functionality that can understand .CSV files. This can be automated and can in fact run on either a PC or the IBM i itself.
Another great option would be an RPG program, back in 2008 Scott Klement wrote a CSV parser in RPG. He's since enhanced it to make it easier to use by taking advantage of RPG's DATA-INTO op-code.
Lastly it's 2023...node.js, PHP, Python are all available on the IBM i and all of them have libraries/packages to handle CSV and write to a DB table.
I'm trying to convert a piece of SQL code to HiveQL, and it's not working as expected.
Please find below the code snippet in SQL that I'm attempting to convert:
SQL Code:
UPDATE
C
SET
C.prod_l = P.prod_l, C.numprod = P.numprod, C.prod_cng = P.prod_cng
FROM
[cnc].dbo.[c_cnc_analysis] C
LEFT JOIN
(
SELECT
X.*,
Len(prod_l) - Len(Replace(prod_l, ' ~ ', ' ')) + 1 AS NumProd,
CASE
WHEN
Len(prod_l) - Len(Replace(prod_l, ' ~ ', ' ')) + 1 = 1
THEN
0
ELSE
1
END
AS PROD_CNG
FROM
(
SELECT DISTINCT
ST2.uitid,
Substring((
SELECT
' ~ ' + ST1.product_id AS [text()]
FROM
(
SELECT
[uitid],
[product_id]
FROM
dbo.[c_cnc_dedup_bse]
GROUP BY
[uitid],
[product_id]
)
ST1
WHERE
ST1.uitid = ST2.uitid
ORDER BY
ST1.uitid FOR xml path ('')), 4, 1000 ) [PROD_L]
FROM
(
SELECT
[uitid],
[product_id]
FROM
dbo.[c_cnc_dedup_bse]
GROUP BY
[uitid],
[product_id]
)
ST2
)
X
)
P
ON C.uitid = P.uitid;
Converted HIVE Query:
create
or replace view prd_temp as
SELECT
`UITID`,
`PRODUCT_ID`
FROM
`C_CNC_DEDUP_BSE`
GROUP BY
`UITID`,
`PRODUCT_ID`;
create
or replace view prd_temp2 as
SELECT
`UITID`,
`PRODUCT_ID`
FROM
`C_CNC_DEDUP_BSE`
GROUP BY
`UITID`,
`PRODUCT_ID`;
create
or replace view prd_temp3 as
SELECT
st1.`uitid`,
concat(' ~ ', st1.`PRODUCT_ID`) AS `text()`
FROM
prd_temp ST1
left join
prd_temp2 st2
on ST1.`UITID` = ST2.`UITID`
where
st1.`UITID` = st2.`UITID`
ORDER BY
ST1.`UITID`;
create
or replace view prd_temp4 as
SELECT
st1.`uitid`,
concat_ws('''', `text()`)
FROM
prd_temp3 ST1
ORDER BY
ST1.`UITID`;
create
or replace view st2 as
SELECT DISTINCT
`UITID`,
SUBSTRING(`_c1` , 4, 1000) as `PROD_L`
FROM
prd_temp4;
create
or replace view x as
SELECT
*,
LENGTH(PROD_L) - LENGTH(REPLACE(PROD_L, ' ~ ', ' ')) + 1 as NumProd,
CASE
WHEN
LENGTH(PROD_L) - LENGTH(REPLACE(PROD_L, ' ~ ', ' ')) + 1 = 1
then
0
ELSE
1
END
as PROD_CNG
from
ST2;
create table C_CNC_ANALYSIS1 as
select
c.*,
P.numprod as numprod,
p.prod_cng as prod_cng,
p.prod_l as prod_l
from
`C_CNC_ANALYSIS` C
LEFT JOIN
X P
ON C.UITID = P.UITID ;
SELECT
*
from
c_cnc_analysis1 limit 100;
Appreciate all the help with this. I think the code converted for the XML path is not working in HIVE, since I'm getting multiple UITIDs (key) and the information in separate rows rather than just one single record per UITID.
Thank You,
Viswanath Sitaraman
I am using a CTE to explode out a Bill of Materials and need to locate all those materials that have recursive components.
What I was attempting, was to limit the number of cycles (levels) deep, by setting BOM_Level in the child node to a maximum bound:
exec pr_sys_drop_object '#BOMExploded'
;with BOM
as
(
select
Prod_Plant_CD
, Demand_Plant_CD
, material_cd
, component_cd
, component_quantity
, component_quantity AS Calculated_Component_Quantity
, BOM_Level
, Demand_Quantity
, CONVERT(float,1) AS Produced_Ratio
, Material_CD AS Demand_Material_CD
from #firstLevel a
UNION ALL
SELECT
b.Plant_CD as 'Prod_Plant_CD'
, a.Demand_Plant_CD
, b.Material_CD
, b.Component_CD
, b.component_quantity
, b.component_quantity
, a.BOM_Level + 1
, a.Demand_Quantity
, a.Produced_Ratio * a.Component_Quantity -- Produced Quantity for the current level = Produced Quantity (level -1) * Component_Quantity (level -1)
, a.Demand_Material_CD
FROM BOM a
inner join #BOM_ProdVersion_Priority b
on a.component_cd = b.material_cd
inner join #base_routes c
on a.Demand_Plant_CD = c.Recipient_Plant_CD
and b.Plant_CD = c.Source_Plant_CD
and c.Material_CD = b.Material_CD -- Need to have material_cd to link
where b.Material_CD != b.Component_CD
and b.Component_Quantity > 0
and BOM_Level < 5 -- Give the max number of levels deep we are allowed to cyncle to
)
select *
into #BOMExploded
from BOM
OPTION (MAXRECURSION 20)
Using this method however, would require a post-process to locate when the cycling on the recursive component level started, then back trace.
How can a CTE recursive query be stopped given a certain condition?
ie. when top-level material_cd = component_cd for a deeper BOM_Level
If I understand you correctly, you don't need to stop at a certain depth/level, or rather you want to stop at a certain level, but you also need to stop in case you start cycling through materials repeatedly.
In the case of the following recursive path: mat_1->mat_2->mat_3->mat_1, you would want to stop before that last mat_1 starts cycling again to mat_2 and so on.
If that's correct, then your best bet is to add a Path field to your recursive query that tracks each term that it finds as it moves down the recursive path:
exec pr_sys_drop_object '#BOMExploded'
;with BOM
as
(
select
Prod_Plant_CD
, Demand_Plant_CD
, material_cd
, component_cd
, component_quantity
, component_quantity AS Calculated_Component_Quantity
, BOM_Level
, Demand_Quantity
, CONVERT(float,1) AS Produced_Ratio
, Material_CD AS Demand_Material_CD
, CAST(material_cd AS VARCHAR(100)) AS Path
from #firstLevel a
UNION ALL
SELECT
b.Plant_CD as 'Prod_Plant_CD'
, a.Demand_Plant_CD
, b.Material_CD
, b.Component_CD
, b.component_quantity
, b.component_quantity
, a.BOM_Level + 1
, a.Demand_Quantity
, a.Produced_Ratio * a.Component_Quantity -- Produced Quantity for the current level = Produced Quantity (level -1) * Component_Quantity (level -1)
, a.Demand_Material_CD
, a.Path + '|' + b.material_cd
FROM BOM a
inner join #BOM_ProdVersion_Priority b
on a.component_cd = b.material_cd
inner join #base_routes c
on a.Demand_Plant_CD = c.Recipient_Plant_CD
and b.Plant_CD = c.Source_Plant_CD
and c.Material_CD = b.Material_CD -- Need to have material_cd to link
where b.Material_CD != b.Component_CD
and b.Component_Quantity > 0
and BOM_Level < 5 -- Give the max number of levels deep we are allowed to cyncle to
and a.path NOT LIKE '%' + b.material_cd + '%'
)
select *
into #BOMExploded
from BOM
OPTION (MAXRECURSION 20)
Now you have a path that is pipe delimited and you can test your current material_cd to see if it's already in the path. If it is, then you end that leg of the recursion to prevent cycling.
Updating to include a version where we capture material_cd cycles and only report those at the end of the recursion:
exec pr_sys_drop_object '#BOMExploded'
;with BOM
as
(
select
Prod_Plant_CD
, Demand_Plant_CD
, material_cd
, component_cd
, component_quantity
, component_quantity AS Calculated_Component_Quantity
, BOM_Level
, Demand_Quantity
, CONVERT(float,1) AS Produced_Ratio
, Material_CD AS Demand_Material_CD
, CAST(material_cd AS VARCHAR(100)) AS Path
, CAST(NULL AS CHAR(5)) as Cycle_Flag
, 0 as Cycle_Depth
from #firstLevel a
UNION ALL
SELECT
b.Plant_CD as 'Prod_Plant_CD'
, a.Demand_Plant_CD
, b.Material_CD
, b.Component_CD
, b.component_quantity
, b.component_quantity
, a.BOM_Level + 1
, a.Demand_Quantity
, a.Produced_Ratio * a.Component_Quantity -- Produced Quantity for the current level = Produced Quantity (level -1) * Component_Quantity (level -1)
, a.Demand_Material_CD
, a.Path + '|' + b.material_cd
, CASE WHEN a.path NOT LIKE '%' + b.material_cd + '%' then 'Cycle' END AS Cycle_Flag,
, CASE WHEN a.path NOT LIKE '%' + b.material_cd + '%' then a.Cycle_Depth + 1 END as Cycle_Depth
FROM BOM a
inner join #BOM_ProdVersion_Priority b
on a.component_cd = b.material_cd
inner join #base_routes c
on a.Demand_Plant_CD = c.Recipient_Plant_CD
and b.Plant_CD = c.Source_Plant_CD
and c.Material_CD = b.Material_CD -- Need to have material_cd to link
where b.Material_CD != b.Component_CD
and b.Component_Quantity > 0
and a.cycle_depth < 2 --stop the query if we start cycling, but only after we capture at least one full cycle
)
select *
into #BOMExploded
from BOM
WHERE cycle_flag IS NOT NULL
OPTION (MAXRECURSION 20)
This will capture cycle_depth which is a counter that measures how deep into a cycle we get. We stop the recursion after we get to cycle_depth of 1 so the cycle can be captures in the final select.
I have a query that I am using where I only know what variables will be retrieved at run time. I'm using a view to pull all of the variables into a single data set then querying against that data set. It looks something like this:
All variables in the SQL db:
Table A.1, Table A.2, Table A.3
Table B.1, Table B.2, Table B.3
Table C.1, Table C.2, Table C.3
At run time I know that I want the variables Table A.1 and Table A.2 where Table A.1 = SomeNumber. I therefore create a view as:
View 1 = Table A.1, Table B.1
I then query against that view where Table A.1 = SomeNumber
This approach seems to work but it take a long time (30 seconds) to return results because I have 20+ tables and 100+ variables. There are 2K+ records to query against.
Any ideas on how I can improve the response time of this query?
******* HERE IS THE ACTUAL QUERY **********
USE [ays_restructuring_league_live];
GO
ALTER PROCEDURE [dbo].[sp_getVolunteerSummaryDetails]
(#LeagueId int, #p_SearchCriteria varchar(MAX), #p_DataflowId int=null)
WITH
EXECUTE AS CALLER
AS
Begin
SET NOCOUNT ON;
DECLARE #Statement AS varchar(MAX);
Declare #p_DataFieldName as varchar(max);
declare #p_Label as varchar(max);
if (CHARINDEX('DisplayId = ''1'' ',#p_SearchCriteria)>0)/* for multiple record*/
begin
Select b.* into #finalTable from(
SELECT distinct VSI.VolunteerSeasonalId,
VI.VolunteerId,
right(MUS.DetailIdURL_Structure + cast(convert(varchar(max),VI.VolunteerId) as varchar(max)),MUS.DetailIdURL_Length) as NewVolunteerId,
right(MUS.OtherURL_Structure + cast(convert(varchar(max),VSI.SeasonId) as varchar(max)),MUS.OtherURL_Length) as NewSeasonId,
UI.FirstName as VolunteerFirstName,
UI.LastName as VolunteerLastName,
UI.LastName+ ', '+ UI.FirstName as VolunteerName,
UI.Email as VolunteerEmail,
VI.ShirtSizeId,
MUSZ.Size as ShirtSize,
UI.HomePhone as VolunteerHomePhone,
UI.MobilePhone as VolunteerMobilePhone,
UI.WorkPhone as VolunteerWorkPhone,
--convert(varchar,UI.BirthDate,101) as VolunteerBirthDate,
--UI.Address,
--UI.StateId,
--MST.Abbreviation as State,
--UI.CityId,
--MC.Abbreviation as City,
--UI.Zip,
--VI.DrivingLicenceNumber,
--UI.Gender as VolunteerGender,
--VSI.CreatedBy,
--VSI.CreatedOn,
--VSI.UpdatedBy,
--VSI.UpdatedOn,
VSI.StatusId,
VSI.SeasonId,
(SELECT substring ( (SELECT ', ' + cast (b.[Day] as varchar)
FROM (select MD.[Day]
from dbo.Master_Day MD where MD.DayID in (select items from dbo.udf_Split(PP.DaysCanNotPractice, ',')))
b for xml path ('')),2,10000)) as DaysCanNotPractice,
(SELECT substring ( (SELECT ', ' + cast (b.[Time] as varchar)
FROM (select PT.[Time]
from dbo.PreferedTime PT where PT.PreferedTimeId in (select items from dbo.udf_Split(PP.TimeCanNotPractice, ',')))
b for xml path ('')),2,10000)) as TimeCanNotPractice,
--PP.LocationId,
--PP.LocationRankId,
(select substring((select ', ' + cast (b.ShortName as varchar)
from (select ML.ShortName
from dbo.Master_Location ML
where ML.LocationID in (select items from dbo.udf_Split(PP.LocationId, ',')))
as b for xml path('')),2,1000000)) as ShortName,
(SELECT MR.[Rank]
FROM dbo.Master_Rank MR
WHERE MR.RankID = PP.LocationRankId) as LocationRank,
--PP.DayOfWeekId,
--PP.DayOfWeekRankId,
(select substring((select ', ' + cast (b.[Day] as varchar)
from (select MD.[Day] from dbo.Master_Day MD
where MD.DayID in (select items from dbo.udf_Split(PP.DayOfWeekId,',')))
as b for xml path('')),2,1000000)) as [DayOfWeek],
(select MR.[Rank]
from dbo.Master_Rank MR
where MR.RankID = PP.DayOfWeekRankId)AS DayOfWeekRank,
--PP.TimeOfDayId,
--PP.TimeOfDayRankId,
(select substring((select ', ' + cast (b.[Time] as varchar)
from (select [Time]
from dbo.PreferedTime PT
where PT.PreferedTimeId in (select items from dbo.udf_Split(PP.TimeOfDayId,',')))
as b for xml path('')),2,1000000)) as TimeOfDay,
(SELECT MR.[Rank]
FROM dbo.Master_Rank MR
WHERE MR.RankID = PP.TimeOfDayRankId) as TimeOfDayRank,
--case when MVP.VolunteerPosition is null then '' else ( case when MD.Abbreviation is null then MVP.VolunteerPosition else '('+MD.Abbreviation+') '+MVP.VolunteerPosition end)end as VolunteeredPosition,
--case when MVP.VolunteerPosition is null then '' else ( case when VRP.PositionId>5 then MVP.VolunteerPosition else '('+MD.Abbreviation+') '+MVP.VolunteerPosition end)end as VolunteeredPosition,
case when MVP.VolunteerPosition is null then '' else
case when VRP.PositionId>5 then MVP.VolunteerPosition else
case when MD.Abbreviation is null then MVP.VolunteerPosition else
'('+MD.Abbreviation+') '+MVP.VolunteerPosition end
end
end as VolunteeredPosition,
case when VRP.PositionId is null then '' else convert(varchar(50),VRP.PositionId) end as VolunteeredPositionId,
case when VRP.DivisionId is null then '' else convert(varchar(50),VRP.DivisionId) end as VolunteeredDivisionId,
'' as AssignedPosition,
'' as AssignedVolunteerPositionId,
'' as AssignedDivisionId,
(SELECT substring ( (SELECT '; ' + cast (b.PlayerName AS varchar(max))
FROM (SELECT DISTINCT ('('+MD.Abbreviation+') '+ PPI.PlayerLastName + ', '+PPI.PlayerFirstName+'$'+'001'+right(MUS.DetailIdURL_Structure + cast(convert(varchar(max),PPI.PlayerId) as varchar(max)),MUS.DetailIdURL_Length)) AS PlayerName
FROM dbo.Player_PermanentInfo PPI,dbo.Player_SeasonalInfo PSI,dbo.Master_Division MD
WHERE (PPI.ParentId1=UI.UserId or PPI.ParentId2=UI.UserId)
and PSI.PlayerId=PPI.PlayerId
and PSI.IsAvailable=1 and PSI.SeasonId=VSI.SeasonID
and PSI.DivisionId=MD.DivisionId
)b FOR XML PATH ( '' )),2,100000))AS PlayerName,
/*
(SELECT substring ( (SELECT ';' + cast (b.PlayerLastName AS varchar(max))
FROM (SELECT DISTINCT PPI.PlayerLastName
FROM dbo.Player_PermanentInfo PPI,dbo.Player_SeasonalInfo PSI,dbo.Master_Division MD
WHERE (PPI.ParentId1=UI.UserId or PPI.ParentId2=UI.UserId)
and PSI.PlayerId=PPI.PlayerId
and PSI.IsAvailable=1 and PSI.SeasonId=VSI.SeasonID
and PSI.DivisionId=MD.DivisionId
)
b
FOR XML PATH ( '' )),
2,
100000
))
AS PlayerLastName,
(SELECT substring ( (SELECT ';' + cast (b.PlayerFirstName AS varchar(max))
FROM (SELECT DISTINCT PPI.PlayerFirstName
FROM dbo.Player_PermanentInfo PPI,dbo.Player_SeasonalInfo PSI,dbo.Master_Division MD
WHERE (PPI.ParentId1=UI.UserId or PPI.ParentId2=UI.UserId)
and PSI.PlayerId=PPI.PlayerId
and PSI.IsAvailable=1 and PSI.SeasonId=VSI.SeasonID
and PSI.DivisionId=MD.DivisionId
)
b
FOR XML PATH ( '' )),
2,
100000
))
AS PlayerFirstName,*/
/*(SELECT substring ((SELECT ','
+ cast (b.ColorID AS varchar)
FROM (SELECT DISTINCT (VBGD.ColorID)
FROM dbo.VolunteerBackGroundDetail VBGD,dbo.Master_Color MCL
WHERE MCL.ColorID= VBGD.ColorID
and VBGD.VolunteerId = VSI.VolunteerId --VBGD.VolunteerSeasonalID = VSI.VolunteerSeasonalId
)
b
FOR XML PATH ( '' )),
2,
100000
))
AS Result,*/
(SELECT substring((SELECT ','
+ cast (b.CheckTypeID AS varchar)
FROM (SELECT DISTINCT (VBI.CheckTypeID)
FROM dbo.Volunteer_BackgroundInfo VBI
WHERE VBI.VolunteerId = VSI.VolunteerId --VBGD.VolunteerSeasonalID = VSI.VolunteerSeasonalId
)
b
FOR XML PATH ( '' )),
2,
100000
))
AS BGCheckType,
(SELECT substring ((SELECT ','
+ cast (b.ColorName AS varchar)
FROM (SELECT DISTINCT (MCL.ColorName)
FROM dbo.Volunteer_BackgroundInfo VBI,dbo.Master_Color MCL
WHERE MCL.ColorID= VBI.ColorID
and VBI.VolunteerId = VI.VolunteerId --VBGD.VolunteerSeasonalID = VSI.VolunteerSeasonalId
)
b
FOR XML PATH ( '' )),
2,
100000
))
AS BGCheckResult,
/*(SELECT substring((SELECT ','
+ cast (b.CheckType AS varchar)
FROM (SELECT DISTINCT (MVCT.CheckType)
FROM dbo.Volunteer_BackgroundInfo VBI,dbo.Master_VolunteerCheckType MVCT
WHERE VBI.VolunteerId = VSI.VolunteerId --VBGD.VolunteerSeasonalID = VSI.VolunteerSeasonalId
and VBI.CheckTypeID=MVCT.CheckTypeId)
b
FOR XML PATH ( '' )),
2,
100000
))
AS CheckType,*/
(SELECT substring((SELECT ','
+ cast (b.DatePerformed AS varchar)
FROM (SELECT DISTINCT Convert(varchar,VBI.DatePerformed,101) as DatePerformed
FROM dbo.Volunteer_BackgroundInfo VBI
WHERE VBI.VolunteerId = VI.VolunteerId --VBGD.VolunteerSeasonalID = VSI.VolunteerSeasonalId
)
b FOR XML PATH ( '' )),2,100000))AS BGCheckDate,
/*(SELECT substring((SELECT ','+ cast(b.EventId as varchar(max))
from(select distinct VCD.EventId
from CheckIn_VolunteerCheckInDetails VCD,CheckIn_CoachCheckInDetails CCD
where VCD.EventId=CCD.EventId
and (VCD.VolunteerSeasonalId=VSI.VolunteerSeasonalId or CCD.VolunteerSeasonalId=VSI.VolunteerSeasonalId))
b for xml path('')),2,100000)) as CheckInEventID,*/
--'' as CheckInEventID,
/*(SELECT substring((SELECT ', '+ cast(b.EventName as varchar(max))
from(select distinct CEM.EventName
from CheckIn_EventMaster CEM, CheckIn_VolunteerCheckInDetails VCD,CheckIn_CoachCheckInDetails CCD
where CEM.CheckInEventId=VCD.EventId AND CEM.CheckInEventId=CCD.EventId
and (VCD.VolunteerSeasonalId=VSI.VolunteerSeasonalId or CCD.VolunteerSeasonalId=VSI.VolunteerSeasonalId))
b for xml path('')),2,100000)) as CheckInEventName,*/
/*(SELECT substring((SELECT ','+ cast(b.EventId as varchar(max))
from(select distinct VCD.EventId
from CheckIn_VolunteerCheckInDetails VCD
where VCD.VolunteerSeasonalId=VSI.VolunteerSeasonalId)
b for xml path('')),2,100000)) as CheckInEventID,
(SELECT substring((SELECT ', '+ cast(b.EventName as varchar(max))
from(select distinct CEM.EventName
from CheckIn_EventMaster CEM, CheckIn_VolunteerCheckInDetails VCD
where CEM.CheckInEventId=VCD.EventId
and VCD.VolunteerSeasonalId=VSI.VolunteerSeasonalId)
b for xml path('')),2,100000)) as CheckInEventName,*/
/*(SELECT substring((SELECT ','
+ cast (b.DatePerformed AS varchar)
FROM (SELECT DISTINCT Convert(varchar,VBI.DatePerformed,101) as DatePerformed
FROM dbo.Volunteer_BackgroundInfo VBI
WHERE VBI.VolunteerId = VSI.VolunteerId --VBGD.VolunteerSeasonalID = VSI.VolunteerSeasonalId
)
b
FOR XML PATH ( '' )),
2,
100000
))
AS DatePerformed,*/
/*case when exists(select *
from dbo.VolunteerApproval
where VolunteerApproval.VolunteerSeasonalID = VSI.VolunteerSeasonalId
and VolunteerApproval.LeagueId = VSI.LeagueId
and VolunteerApproval.ApprovedStatus = 1) then 'i_tick.gif' else 'remove_Icon.png' end as IsApproved, */
VSI.VolunteerSeasonalStatusId as Approved,
case when VSI.VolunteerSeasonalStatusId = 1 then 'i_tick.gif' else 'remove_Icon.png' end as IsApproved ,
--,MS.SeasonName
'1' as DisplayId,
case when VSI.SeasonId = 8 then '2014/15 Regular Season' else
case when VSI.SeasonId = 7 then '2013/14 Regular Season' else '2014/15 FYBA Fall Academy'
end
end as SeasonName,
VSI.SchedulingPriority
--into #finalTable
FROM dbo.Master_Url_Setting MUS, dbo.Volunteer_Info VI
inner join dbo.Volunteer_SeasonalInfo VSI on VSI.VolunteerId = VI.VolunteerId
inner join User_Info UI on UI.UserId=VI.UserId
inner JOIN dbo.Volunteer_Requested_Position VRP
ON VRP.VolunteerSeasonalId = VSI.VolunteerSeasonalId
LEFT OUTER JOIN dbo.Master_UniformSize MUSZ
ON MUSZ.UniformSizeId = VI.ShirtSizeId
left OUTER JOIN dbo.PracticePreference PP
ON PP.VolunteerSeasonalId = VSI.VolunteerSeasonalId
--left OUTER JOIN dbo.Volunteer_Requested_Position VRP
--ON VRP.VolunteerSeasonalId = VSI.VolunteerSeasonalId
left outer join dbo.Master_Division MD
ON VRP.DivisionId = MD.DivisionId
left outer join dbo.Master_VolunteerPosition MVP
ON MVP.VolunteerPositionId = VRP.PositionId
WHERE VSI.IsAvailable = 1
AND VSI.LeagueId = #LeagueId
and VSI.Seasonid in (7,8,9)
--and VSI.VolunteerId=878
union
SELECT distinct VSI.VolunteerSeasonalId,
VI.VolunteerId,
right(MUS.DetailIdURL_Structure + cast(convert(varchar(max),VI.VolunteerId) as varchar(max)),MUS.DetailIdURL_Length) as NewVolunteerId,
right(MUS.OtherURL_Structure + cast(convert(varchar(max),VSI.SeasonId) as varchar(max)),MUS.OtherURL_Length) as NewSeasonId,
UI.FirstName as VolunteerFirstName,
UI.LastName as VolunteerLastName,
UI.LastName+ ', '+ UI.FirstName as VolunteerName,
UI.Email as VolunteerEmail,
VI.ShirtSizeId,
MUSZ.Size as ShirtSize,
UI.HomePhone as VolunteerHomePhone,
UI.MobilePhone as VolunteerMobilePhone,
UI.WorkPhone as VolunteerWorkPhone,
--convert(varchar,UI.BirthDate,101) as VolunteerBirthDate,
--UI.Address,
--UI.StateId,
--MST.Abbreviation as State,
--UI.CityId,
--MC.Abbreviation as City,
--UI.Zip,
--VI.DrivingLicenceNumber,
--UI.Gender as VolunteerGender,
--VSI.CreatedBy,
--VSI.CreatedOn,
--VSI.UpdatedBy,
--VSI.UpdatedOn,
VSI.StatusId,
VSI.SeasonId,
(SELECT substring ( (SELECT ', ' + cast (b.[Day] as varchar)
FROM (select MD.[Day]
from dbo.Master_Day MD where MD.DayID in (select items from dbo.udf_Split(PP.DaysCanNotPractice, ',')))
b for xml path ('')),2,10000)) as DaysCanNotPractice,
(SELECT substring ( (SELECT ', ' + cast (b.[Time] as varchar)
FROM (select PT.[Time]
from dbo.PreferedTime PT where PT.PreferedTimeId in (select items from dbo.udf_Split(PP.TimeCanNotPractice, ',')))
b for xml path ('')),2,10000)) as TimeCanNotPractice,
--PP.LocationId,
--PP.LocationRankId,
(select substring((select ', ' + cast (b.ShortName as varchar)
from (select ML.ShortName
from dbo.Master_Location ML
where ML.LocationID in (select items from dbo.udf_Split(PP.LocationId, ',')))
as b for xml path('')),2,1000000)) as ShortName,
(SELECT MR.[Rank]
FROM dbo.Master_Rank MR
WHERE MR.RankID = PP.LocationRankId) as LocationRank,
--PP.DayOfWeekId,
--PP.DayOfWeekRankId,
(select substring((select ', ' + cast (b.[Day] as varchar)
from (select MD.[Day] from dbo.Master_Day MD
where MD.DayID in (select items from dbo.udf_Split(PP.DayOfWeekId,',')))
as b for xml path('')),2,1000000)) as [DayOfWeek],
(select MR.[Rank]
from dbo.Master_Rank MR
where MR.RankID = PP.DayOfWeekRankId)AS DayOfWeekRank,
--PP.TimeOfDayId,
--PP.TimeOfDayRankId,
(select substring((select ', ' + cast (b.[Time] as varchar)
from (select [Time]
from dbo.PreferedTime PT
where PT.PreferedTimeId in (select items from dbo.udf_Split(PP.TimeOfDayId,',')))
as b for xml path('')),2,1000000)) as TimeOfDay,
(SELECT MR.[Rank]
FROM dbo.Master_Rank MR
WHERE MR.RankID = PP.TimeOfDayRankId) as TimeOfDayRank,
'' as VolunteeredPosition,
'' as VolunteeredPositionId,
'' as VolunteeredDivisionId,
case when AMVP.VolunteerPosition is null then '' else (case when TV.VolunteerPositionId>5 then AMVP.VolunteerPosition else '('+AMD.Abbreviation+') '+AMVP.VolunteerPosition end)end as AssignedPosition,
--case when AMVP.VolunteerPosition is null then '' else(case when AMD.Abbreviation is null then AMVP.VolunteerPosition else '('+AMD.Abbreviation+') '+AMVP.VolunteerPosition end)end as AssignedPosition,
case when TV.VolunteerPositionId is null then '' else convert(varchar(50),TV.VolunteerPositionId) end as AssignedVolunteerPositionId,
case when MT.DivisionId is null then '' else convert(varchar(50),MT.DivisionId) end as AssignedDivisionId,
(SELECT substring ( (SELECT '; ' + cast (b.PlayerName AS varchar(max))
FROM (SELECT DISTINCT ('('+MD.Abbreviation+') '+ PPI.PlayerLastName + ', '+PPI.PlayerFirstName+'$'+'001'+right(MUS.DetailIdURL_Structure + cast(convert(varchar(max),PPI.PlayerId) as varchar(max)),MUS.DetailIdURL_Length)) AS PlayerName
FROM dbo.Player_PermanentInfo PPI,dbo.Player_SeasonalInfo PSI,dbo.Master_Division MD
WHERE (PPI.ParentId1=UI.UserId or PPI.ParentId2=UI.UserId)
and PSI.PlayerId=PPI.PlayerId
and PSI.IsAvailable=1 and PSI.SeasonId=VSI.SeasonID
and PSI.DivisionId=MD.DivisionId
)b FOR XML PATH ( '' )),2,100000))AS PlayerName,
(SELECT substring((SELECT ','
+ cast (b.CheckTypeID AS varchar)
FROM (SELECT DISTINCT (VBI.CheckTypeID)
FROM dbo.Volunteer_BackgroundInfo VBI
WHERE VBI.VolunteerId = VSI.VolunteerId --VBGD.VolunteerSeasonalID = VSI.VolunteerSeasonalId
)
b
FOR XML PATH ( '' )),
2,
100000
))
AS BGCheckType,
(SELECT substring ((SELECT ','
+ cast (b.ColorName AS varchar)
FROM (SELECT DISTINCT (MCL.ColorName)
FROM dbo.Volunteer_BackgroundInfo VBI,dbo.Master_Color MCL
WHERE MCL.ColorID= VBI.ColorID
and VBI.VolunteerId = VI.VolunteerId --VBGD.VolunteerSeasonalID = VSI.VolunteerSeasonalId
)
b
FOR XML PATH ( '' )),
2,
100000
))
AS BGCheckResult,
(SELECT substring((SELECT ','
+ cast (b.DatePerformed AS varchar)
FROM (SELECT DISTINCT Convert(varchar,VBI.DatePerformed,101) as DatePerformed
FROM dbo.Volunteer_BackgroundInfo VBI
WHERE VBI.VolunteerId = VI.VolunteerId --VBGD.VolunteerSeasonalID = VSI.VolunteerSeasonalId
)
b FOR XML PATH ( '' )),2,100000))AS BGCheckDate,
VSI.VolunteerSeasonalStatusId as Approved,
case when VSI.VolunteerSeasonalStatusId = 1 then 'i_tick.gif' else 'remove_Icon.png' end as IsApproved ,
--,MS.SeasonName
'1' as DisplayId,
case when VSI.SeasonId = 8 then '2014/15 Regular Season' else
case when VSI.SeasonId = 7 then '2013/14 Regular Season' else '2014/15 FYBA Fall Academy'
end
end as SeasonName,
VSI.SchedulingPriority
--into #finalTable
FROM dbo.Master_Url_Setting MUS, dbo.Volunteer_Info VI
inner join dbo.Volunteer_SeasonalInfo VSI on VSI.VolunteerId = VI.VolunteerId
inner join User_Info UI on UI.UserId=VI.UserId
inner JOIN dbo.TeamVolunteers TV
ON TV.VolunteerSeasonalId= VSI.VolunteerSeasonalId
LEFT OUTER JOIN dbo.Master_UniformSize MUSZ
ON MUSZ.UniformSizeId = VI.ShirtSizeId
left OUTER JOIN dbo.PracticePreference PP
ON PP.VolunteerSeasonalId = VSI.VolunteerSeasonalId
--left OUTER JOIN dbo.TeamVolunteers TV
--ON TV.VolunteerSeasonalId= VSI.VolunteerSeasonalId
LEFT OUTER JOIN dbo.Master_Teams MT
ON MT.TeamId = TV.TeamId
left outer join dbo.Master_Division AMD
ON MT.DivisionId = AMD.DivisionId
left outer join dbo.Master_VolunteerPosition AMVP
ON AMVP.VolunteerPositionId = TV.VolunteerPositionId
WHERE VSI.IsAvailable = 1
AND VSI.LeagueId = #LeagueId
and VSI.Seasonid in (7,8,9)
--and VSI.VolunteerId=878
)b
--where VolunteerSeasonalId=7225
OPTION (FORCE ORDER);
IF #p_DataflowId IS NULL
BEGIN
SET #Statement = 'Select * from #finalTable ' + #p_SearchCriteria+' OPTION (FORCE ORDER)';
EXEC (#Statement);
END
ELSE
BEGIN
CREATE TABLE [#tempExportFields]([DataFieldName] varchar(max),Label varchar(max));
Set #Statement = 'Select '
insert into #tempExportFields exec sp_getControlsorderingForExport #p_DataflowId;
set #Statement = 'Select '+(select substring((select ', '+ b.Label from (Select DataFieldName +' as ' + '['+ Label +']' as Label from #tempExportFields) as b for xml path('')),2,100000)) + ' from #finalTable ' + #p_SearchCriteria;
--select (#Statement);
EXEC (#Statement);
DROP TABLE #tempExportFields;
END
DROP TABLE #finalTable;
SET NOCOUNT OFF;
end
else /* for single Record record*/
begin
SELECT distinct VSI.VolunteerSeasonalId,
VI.VolunteerId,
right(MUS.DetailIdURL_Structure + cast(convert(varchar(max),VI.VolunteerId) as varchar(max)),MUS.DetailIdURL_Length) as NewVolunteerId,
right(MUS.OtherURL_Structure + cast(convert(varchar(max),VSI.SeasonId) as varchar(max)),MUS.OtherURL_Length) as NewSeasonId,
UI.FirstName as VolunteerFirstName,
UI.LastName as VolunteerLastName,
UI.LastName+ ', '+ UI.FirstName as VolunteerName,
UI.Email as VolunteerEmail,
VI.ShirtSizeId,
MUSZ.Size as ShirtSize,
UI.HomePhone as VolunteerHomePhone,
UI.MobilePhone as VolunteerMobilePhone,
UI.WorkPhone as VolunteerWorkPhone,
--convert(varchar,UI.BirthDate,101) as VolunteerBirthDate,
--UI.Address,
--UI.StateId,
--MST.Abbreviation as State,
--UI.CityId,
--MC.Abbreviation as City,
--UI.Zip,
--VI.DrivingLicenceNumber,
--UI.Gender as VolunteerGender,
--VSI.CreatedBy,
--VSI.CreatedOn,
--VSI.UpdatedBy,
--VSI.UpdatedOn,
VSI.StatusId,
VSI.SeasonId,
(SELECT substring ( (SELECT ', ' + cast (b.[Day] as varchar)
FROM (select MD.[Day]
from dbo.Master_Day MD where MD.DayID in (select items from dbo.udf_Split(PP.DaysCanNotPractice, ',')))
b for xml path ('')),2,10000)) as DaysCanNotPractice,
(SELECT substring ( (SELECT ', ' + cast (b.[Time] as varchar)
FROM (select PT.[Time]
from dbo.PreferedTime PT where PT.PreferedTimeId in (select items from dbo.udf_Split(PP.TimeCanNotPractice, ',')))
b for xml path ('')),2,10000)) as TimeCanNotPractice,
--PP.LocationId,
--PP.LocationRankId,
(select substring((select ', ' + cast (b.ShortName as varchar)
from (select ML.ShortName
from dbo.Master_Location ML
where ML.LocationID in (select items from dbo.udf_Split(PP.LocationId, ',')))
as b for xml path('')),2,1000000)) as ShortName,
(SELECT MR.[Rank]
FROM dbo.Master_Rank MR
WHERE MR.RankID = PP.LocationRankId) as LocationRank,
--PP.DayOfWeekId,
--PP.DayOfWeekRankId,
(select substring((select ', ' + cast (b.[Day] as varchar)
from (select MD.[Day] from dbo.Master_Day MD
where MD.DayID in (select items from dbo.udf_Split(PP.DayOfWeekId,',')))
as b for xml path('')),2,1000000)) as [DayOfWeek],
(select MR.[Rank]
from dbo.Master_Rank MR
where MR.RankID = PP.DayOfWeekRankId)AS DayOfWeekRank,
--PP.TimeOfDayId,
--PP.TimeOfDayRankId,
(select substring((select ', ' + cast (b.[Time] as varchar)
from (select [Time]
from dbo.PreferedTime PT
where PT.PreferedTimeId in (select items from dbo.udf_Split(PP.TimeOfDayId,',')))
as b for xml path('')),2,1000000)) as TimeOfDay,
(SELECT MR.[Rank]
FROM dbo.Master_Rank MR
WHERE MR.RankID = PP.TimeOfDayRankId) as TimeOfDayRank,
(SELECT substring ( (SELECT ',' + cast (b.PositionId AS varchar)
FROM (SELECT DISTINCT (VRP1.PositionId)
FROM dbo.Volunteer_Requested_Position VRP1
WHERE VRP1.VolunteerSeasonalId = VSI.VolunteerSeasonalId
)
b
FOR XML PATH ( '' )),
2,
100000
))
AS VolunteeredPositionId,
(SELECT substring ( (SELECT ';' + cast (b.VolunteerPosition AS varchar)
FROM (SELECT DISTINCT (case when VRP1.PositionId>5 then MVP.VolunteerPosition else '('+MD.Abbreviation+') '+MVP.VolunteerPosition end)as VolunteerPosition
FROM dbo.Master_VolunteerPosition MVP,dbo.Volunteer_Requested_Position VRP1
left outer join dbo.Master_Division MD ON VRP1.DivisionId = MD.DivisionId
WHERE MVP.VolunteerPositionId = VRP1.PositionId
AND VRP1.VolunteerSeasonalId = VSI.VolunteerSeasonalId
)
b
FOR XML PATH ( '' )),
2,
100000
))
AS VolunteeredPosition,
/*(SELECT substring ( (SELECT ';' + cast (b.VolunteerPosition AS varchar)
FROM (SELECT DISTINCT (case when MD.Abbreviation is null then MVP.VolunteerPosition else '('+MD.Abbreviation+') '+MVP.VolunteerPosition end)as VolunteerPosition
FROM dbo.Master_VolunteerPosition MVP,dbo.Volunteer_Requested_Position VRP1
left outer join dbo.Master_Division MD ON VRP1.DivisionId = MD.DivisionId
WHERE MVP.VolunteerPositionId = VRP1.PositionId
AND VRP1.VolunteerSeasonalId = VSI.VolunteerSeasonalId
)
b
FOR XML PATH ( '' )),
2,
100000
))
AS VolunteeredPosition,*/
(SELECT substring ( (SELECT ',' + cast (b.DivisionId AS varchar)
FROM (SELECT DISTINCT (VRP1.DivisionId)
FROM dbo.Volunteer_Requested_Position VRP1
WHERE VRP1.VolunteerSeasonalId = VSI.VolunteerSeasonalId
)
b
FOR XML PATH ( '' )),
2,
100000
))
AS VolunteeredDivisionId,
/*(SELECT substring ( (SELECT ', ' + cast (b.Abbreviation AS varchar)
FROM (SELECT DISTINCT (MD.Abbreviation)
FROM dbo.Volunteer_Requested_Position VRP1,dbo.Master_Division MD
WHERE VRP1.VolunteerSeasonalId = VSI.VolunteerSeasonalId
and VRP1.DivisionId=MD.DivisionId
)
b
FOR XML PATH ( '' )),
2,
100000
))
AS Abbreviation,*/ /*VolunteeredDivision*/
(SELECT substring ( (SELECT ',' + cast (b.VolunteerPositionId AS varchar)
FROM (SELECT DISTINCT (TV.VolunteerPositionId)
FROM dbo.TeamVolunteers TV
WHERE TV.VolunteerSeasonalId = VSI.VolunteerSeasonalId
)
b
FOR XML PATH ( '' )),
2,
100000
))
AS AssignedVolunteerPositionId,
(SELECT substring ( (SELECT ';' + cast (b.VolunteerPosition AS varchar)
......TRUNCATED
Let's say there is a table of relationships
(entity_id, relationship, related_id)
1, A, 2
1, A, 3
3, B, 5
1, C, null
12, C, 1
100, C, null
I need a query that will pull all related rows.
For example, if i queried for entity_id = 1, the following rows should be pulled
1, A, 2
1, A, 3
3, B, 5
1, C, null
12, C, 1
Actually, if i queried for entity_id = 1, 2, 3, 5, or 12, the resultset should be the same.
This is different than the standard manager-employee paradigm as there is no hierarchy. The relationships can go in any direction.
EDIT
None of the answers posted thus far worked.
I was able to come up with a solution that works.
I'll give the solution credit to the one who can clean this monstrosity into something more elegant.
with tab as (
-- union for reversals
select id, entity_id, r.related_id, 1 level
, cast('/' + cast(entity_id as varchar(1000)) + '/' as varchar(1000)) path
from _entity_relation r
where not exists(select null from _entity_relation r2 where r2.related_id=r.entity_id)
or r.related_id is null
union
select id, related_id, r.entity_id, 1 level
, cast('/' + cast(related_id as varchar(1000)) + '/' as varchar(1000)) path
from _entity_relation r
where not exists(select null from _entity_relation r2 where r2.related_id=r.entity_id)
or r.related_id is null
-- create recursive path
union all
select r.id, r.entity_id, r.related_id, tab.level+1
, cast(tab.path + '/' + cast(r.entity_id as varchar(100)) + '/' + '/' + cast(r.related_id as varchar(1000)) + '/' as varchar(1000)) path
from _entity_relation r
join tab
on tab.related_id = r.entity_id
)
select x.id
, x.entity_id
,pr.description as relation_description
,pt.first_name + coalesce(' ' + pt.middle_name,'') + ' ' + pt.last_name as relation_name
,CONVERT(CHAR(10), pt.birth_date, 101) as relation_birth_date
from (
select entity_id, MAX(id) as id from (
select distinct tab.id, entity_id
from tab
join(
select path
from tab
where entity_id=#in_entity_id
) p on p.path like tab.path + '%' or tab.path like p.path + '%'
union
select distinct tab.id, related_id
from tab
join(
select path
from tab
where entity_id=#in_entity_id
) p on p.path like tab.path + '%' or tab.path like p.path + '%'
union
select distinct tab.id, entity_id
from tab
join(
select path
from tab
where related_id=#in_entity_id
) p on p.path like tab.path + '%' or tab.path like p.path + '%'
union
select distinct tab.id, related_id
from tab
join(
select path
from tab
where related_id=#in_entity_id
) p on p.path like tab.path + '%' or tab.path like p.path + '%'
) y
group by entity_id
) x
join _entity_relation pr on pr.id = x.id
join _entity pt on pt.id = x.entity_id
where x.entity_id <> #in_entity_id;
Please be careful with you data as to accomplish your task you must avoid circular references. The following query can be optimized but for sure it'll work
;with tab as (
select entity_id, relationship, related_id, 1 level, cast('/' + cast(entity_id as varchar(1000)) as varchar(1000)) path
from #r r
where not exists(select null from #r r2 where r2.related_id=r.entity_id)
or r.related_id is null
union all
select r.entity_id, r.relationship, r.related_id, tab.level+1, cast(tab.path + '/' + cast(r.entity_id as varchar(100)) as varchar(1000)) path
from #r r
join tab
on tab.related_id = r.entity_id
)
select distinct tab.*
from tab
join(
select path
from tab
where entity_id=1) p
on p.path like tab.path + '%' or tab.path like p.path + '%'
Solution using two CTEs
I first created a table with relationships that go both ways and then created a recursive CTE that uses this both ways results to build whole hierarchies with ancestor paths...
with both as
(
select *, 0 as rev
from t
where related_id is not null
union
select *, 1
from t
),
recurs as
(
select *, cast('/' as varchar(100)) as anc
from both
where entity_id is null
union all
select b.*, cast(re.anc + cast(b.entity_id as varchar) + '/' as varchar(100))
from both b
join recurs re
on (re.related_id = b.entity_id)
where charindex('/'+cast(isnull(b.entity_id,'') as varchar)+'/', re.anc) = 0
)
select *
/*
THIS ONE SHOULD BE USED TO RETURN TO ORIGINAL
case when is_reverse = 1 then related_id else entity_id end as entity_id,
relationship,
case when is_reverse = 0 then related_id else entity_id end as related_id
*/
from recurs
where related_id = xXx or
charindex('/'+cast(xXx as varchar)+'/', anc) != 0
Replace xXx with actual value.
This query assumes that root element is the one with entity_id = null, so it builds the whole recursion from there. If that's not the case you'll have to change it accordingly.
I've added loop checks either loops are 1,2,3,4,5,1 or 1,2,3,4,5,3... So total or partial loops. Both will work.