SQL Server 2012 :: Finding Lowest Level Descendants In Hierarchy
Mar 11, 2015
I've got a fairly large hierarchy table and I'm trying to put together a query to find the lowest level descendants of the hierarchy. I think there must be some way to use the "Breadth-first" approach that's stated in the MSDN technet sites about SQL Server HierarchyID but i'm not sure how to write the necessary T-SQL to traverse that. I know I can get all the descendants of a parent node like this
SELECT *
FROM AdventureWorks2012.HumanResources.Employee
WHERE OrganizationNode.IsDescendantOf(@ParentNode) = 1
However, this query returns all levels for that parent's branch. If I just wanted list of employees that were at the lowest level of the branch(es) for this parent node, how would I do this?
I have a table of Affiliates, each Affiliate can have a ParentId, which refers to another Affiliate. How can I retrieve all children of a given Affiliate, along with their depth level? I have this query which selects the total number of descendants of a given Affiliate, but I need to select all the children + their depth level, up to a certain level.
WITH Descendants AS( SELECT RootId = Id, Id FROM Affiliates UNION ALL SELECT RootId, Af.Id FROM Descendants
[Code] .........
What I want to achieve is a statement that has 3 parameters: RefererId, StartLevel, and EndLevel.
I need a statement that selects all the specified Affiliate.ReferrerId's descendants including their level distance from the referrer, filtered by the StartLevel and EndLevel (WHERE CurrentLevel >= StartLevel AND CurrentLevel <= EndLevel ).
CREATE TABLE #tree ( Childid varchar(20), Parentid varchar(20) ) INSERT INTO #tree (Childid,ParentId) SELECT '123' , null UNION ALL SELECT '456' , '123' UNION ALL SELECT '789' , '456' UNION ALL SELECT '870' , '456' UNION ALL SELECT '985' , '870';
Hi,This is probably a classic scenario with a shared dimension that weneed to use in different cubes, where all fact tables do not offer thesame level of detail. Dimension is snow-flaked.The cube that's causing me troubles was designed by marking the lowestdimension level Diabled and not Visible. This allows me to get rid ofone of the snow-flake tables (the one with the lowest level), thusallowing an INNER JOIN with the remaining table which has a level ofdetail corresponding to the fact table.When processing the cube, I get a 'member with key '[blah]' was foundin the fact table but was not found in the level '[blah]' of thedimension '[blah]'' that seems to indicate that none of my fact foreignkeys exist as primary keys in the dimension table. However if I thenattempt to query the cube, all data seems to be there.Would anybody be in a position (and willing ;-)) to share his/her ownexperience working around a similar issue?Thanks,SRL
i tried on CTE but iam not gettng correct result plz help me
Declare @TMaster Table (MasterId int, Type varchar(100), ParentMasterId int) Insert into @Tmaster Select 1, 'Fixed', 14 Union All Select 2, 'Flexible',14 union All Select 3, 'Others',14 union All Select 13, 'Retirement benefits',1 union All Select 14, 'PBHeads', 0
Select * From @Tmaster
Declare @TDetails Table ( MasterId Int, Description varchar(100)) Insert into @TDetails Select 1, 'Basic' union all Select 1,'Conveyance' union all Select 1,'HRA' union all Select 1,'Special Allowance' union all Select 2, 'Children Education' union all Select 2,'Travel Allowance' union all Select 2,'Medical Expenses' union all Select 2,'Variable Spl Pay' union all Select 3, 'Project Allowance' union all Select 3,'Quarterly Incentive' union all Select 3,'Shift Allowance' union all Select 3,'Annual Component' union all Select 13,'Provident Fund' union all Select 13,'Gratuity' union all Select 13,'Super annuation'
Select * From @TDetails
in group list we have to show fixed, flexible, other in subgroups(L1) list under fixed we have to show Basic salary, HRA, Conveyance, Special Allowance,Retirement benefits
in subgroup(L2) we have to show Gratuity, providedfund, Super annuation they are subgroups of retirementbenefits
output : Group Subgroup(L1) Subgroup(L2) Fixed Basic salary HRA Conveyance Special Allowance Retirement benefits Provident Fund Gratuity Super annuation
Flexible reimbursements LTA/Group Travel Medical expenses Children education variable special pay
Others Project allowance Performance incentive Medical insurance
The relationship between state and sales region is n:1, i.e. one state belongs to exactly one sales region, and one sales region can consists of one or multiple states. Unfortunatly I can't define this attribute relationsship in the dimension because it would lead to a diamond-shaped relationsship without a user-defined-hierarchy to back it up. So far that isn't much of a problem, user don't drill down from sales region to state. But now I want to define a calculated member that multiplies a measure from the main measure group with another measure from a weighting factor measure group at the state level and above. The granularity attribute of the geography dimension in the dimension usage tab of the weighting factor measuregroup is the state.
So far what I've got is:
CREATE MEMBER Currentcube.Measures.[weighted measure state and above] AS NULL; SCOPE (Measures.[weighted measure state and above], Descendants(geography.[political territory].[all member],3,SELF_AND_BEFORE), Descendants(geography.[salesterritory].[all member],2,SELF_AND_BEFORE), ... Descendants(geography.[hierarchy 9].[all member],1,SELF_AND_BEFORE)); this = sum(existing(geography.[political territory].state.members), measures.[main measure group measure] * measures.[weighting measure group measure]);END SCOPE;
This works from a functional point of view, but is rather slow when querying any other hierarchy than the political territory hierarchy, because SSAS first goes down from the state level to the key attribute of the geography dimension, and then aggregates from there to the sales region.In other words, I want SSAS to resolve the relationsship (which state belongs to which sales region) through the dimension, and not through the fact, and apply the calculation afterwards. Like some kind of currency conversion, but only from a certain level upwards.
Eg: I have productivity records of each day and each employee. I need to calculate avg of each last level employee productivity by monthly. Again Last level employee productivity avg must be added up with their immediate head. But, when I define a Measure Item as avg in the cube, it sums all the values of lost level employees & head and divides with number of records (normal avg).
My requirement is calculating each head avg by sum of each last level employee avgs / no of employees. If head having value, he too will be added. Again Head’s Avg will be added up immediate head.
The following calculation gives average value at each level.
Average of Level 3(E4) = > (4+3+7+6)/4 = 5 hrs/day< = (E6+E7+E8+E4)/4
Average of Level 2(E2) = > (5+3+5)/3= 4.333 < =avg(Level3(E4))+avg(Level3(E5)))/2
Average of Level 1(E1) = > (4.333+4+1)/3 = 3.111 < = avg(Level3(E2))+avg(Level3(E3)))/2
Formula for average of level : : (Sum of Children value + Head Value of Corresponding children) / (No.of Children +1)
I want to calculate average of each employee as well as average of each level in cube (SQL Server Analysis Services).
I have a table named 'DepartmentItem' which is designed with hierarchy structure. The column 'ParentId' from table DepartmentItem indicates parent-child relationship and department root among records. I have written and run a user-defined function I use recursive approach, but the function runs slowly.
My question: is there a better way to query that hierarchy table instead of using recursive?
** The current user-defined function that is written using recursive:
CREATE FUNCTION dbo.fnGetDepartmentTree ( @departmentItemId int ) RETURNS TABLE AS RETURN with DepartmentItemTree(DepartmentItemId , DepartmentItemTypeId , ParentId, ItemOrder, Level)
[code].....
** And definition of table 'DepartmentItem' :
DepartmentItemId int IDENTITY(1,1) NOT NULL, ParentId int NULL, -- Each department root starts when this column is NULL or the current row is department root. If it is not NULL then the current row has ParentId whose record has DepartmentItemId = ParentId of the current row (see more below) IsActive bit NOT NULL DEFAULT ((1)),
I need to be able to identify breaks in a sequence so I can evaluate the data more correctly. In the sample I have given I need to be able to identify the break in sequence at 69397576, ideally I would set that as a D. My query also needs to recognize that the 3 sequences following 69397576 are sequential and would belong to that set. so the out come would look like this.
SELECT * INTO TEMP FROM (SELECT 'AAAAA' AS CATEGORY, 'A1000' AS CODE, '01-01-2014' AS STARTDATE, '01-31-2014' AS ENDDATE UNION SELECT 'AAAAA' AS CATEGORY, 'A1000' AS CODE, '02-01-2014' AS STARTDATE, '02-28-2014' AS ENDDATE UNION SELECT 'AAAAA' AS CATEGORY, 'A1000' AS CODE, '03-01-2014' AS STARTDATE, '03-31-2014' AS ENDDATE UNION SELECT 'AAAAA' AS CATEGORY, 'A2000' AS CODE, '04-01-2014' AS STARTDATE, '04-30-2014' AS ENDDATE UNION SELECT 'AAAAA' AS CATEGORY, 'A1000' AS CODE, '05-01-2014' AS STARTDATE, '05-31-2014' AS ENDDATE) X
I need to extract the date that the value in CODE column changes to another code for each value of CATEGORY and if there is no change, to record the original CODE value and its startdate for each CATEGORY.
INSERT #Visits (OpportunityID, ActivityID, FirstVisit, ScheduledEnd) SELECT 1, 1001, '2014-08-17', '2014-08-17 12:00:00.000' UNION ALL SELECT 1, 1002, '2014-08-17', '2014-08-17 17:04:13.000' UNION ALL SELECT 2, 1003, '2014-08-18', '2014-08-18 20:39:56.000' UNION ALL
Basically I'd like to mark the first Activity for each OpportunityID as a First Visit if its ScheduledEnd falls on the same day as the FirstVisit, and otherwise mark it as a Repeat Visit.
I have this so far, but it doesn't pick up on that the ScheduledEnd needs to be on the same day as the FirstVisit date to count as a first visit:
SELECT*, CASE MIN(ScheduledEnd) OVER (PARTITION BY FirstVisit) WHEN ScheduledEnd THEN 1 ELSE 0 END AS isFirstVisit, CASE MIN(ScheduledEnd) OVER (PARTITION BY FirstVisit) WHEN ScheduledEnd THEN 0 ELSE 1 END AS isRepeatVisit FROM#Visits
This function will generate all DELETE statements in correct order to perform a CASCADING delete. For self-joined tables, it will generate the T-SQL code to "unwind" the table, also in correct order!CREATE FUNCTION dbo.fnCascadingDelete ( @Schema NVARCHAR(128) = NULL, @Table NVARCHAR(128) = NULL ) RETURNS@Return TABLE ( RowID INT PRIMARY KEY CLUSTERED, IsSelfJoin TINYINT NOT NULL, HasPk TINYINT NOT NULL, [SQL] NVARCHAR(4000) NOT NULL ) AS BEGIN DECLARE@Constraints TABLE ( RowID INT NOT NULL, Indent SMALLINT NOT NULL, [Catalog] NVARCHAR(128) NOT NULL, [Schema] NVARCHAR(128) NOT NULL, [Table] NVARCHAR(128) NOT NULL, [Column] NVARCHAR(128), pkCatalog NVARCHAR(128), pkSchema NVARCHAR(128), pkTable NVARCHAR(128), pkColumn NVARCHAR(128), pkType NVARCHAR(128), pkSize INT, IsSelfJoin TINYINT NOT NULL, HasPk TINYINT NOT NULL )
INSERT@Constraints ( RowID, Indent, [Catalog], [Schema], [Table], [Column], pkCatalog, pkSchema, pkTable, pkColumn, pkType, pkSize, IsSelfJoin, HasPk ) SELECTRowID, Indent, [Catalog], [Schema], [Table], [Column], pkCatalog, pkSchema, pkTable, pkColumn, pkType, pkSize, SelfJoin, CASE WHEN [Column] IS NULL THEN 0 ELSE 1 END FROMdbo.fnTableTree(@Schema, @Table)
IF @@ROWCOUNT = 0 RETURN
DECLARE@SQL TABLE ( ID INT IDENTITY(1, 1), RowID INT PRIMARY KEY CLUSTERED, IsSelfJoin TINYINT NOT NULL, HasPk TINYINT NOT NULL, [SQL] NVARCHAR(4000) NOT NULL )
DECLARE@Unwind TABLE ( RowID INT NOT NULL, StepID INT IDENTITY(0, 1) PRIMARY KEY NONCLUSTERED, [SQL] NVARCHAR(4000) )
WHILE NOT EXISTS (SELECT * FROM @SQL WHERE RowID = 1) BEGIN SELECT TOP 1@RowID = c.RowID, @ID = c.RowID, @Indent = c.Indent, @TSQL = N'', @EndSQL = N'', @IsSelfJoin = c.IsSelfjoin, @HasPk = c.HasPk FROM@Constraints AS c LEFT JOIN@SQL AS s ON s.RowID = c.RowID WHEREs.RowID IS NULL ORDER BYc.Indent DESC, c.RowID DESC
WHILE @ID > 0 BEGIN IF @Indent = 0 SELECT@RowSQL = N'DELETE t' + CAST(@RowID AS NVARCHAR(12)), @RowSQL = @RowSQL + N' FROM ' + QUOTENAME(c.[Catalog]) + N'.' + QUOTENAME(c.[Schema]) + N'.' + QUOTENAME(c.[Table]) + N' AS t' + CAST(@ID AS NVARCHAR(12)), @EndSQL = N' WHERE t' + CAST(@ID AS NVARCHAR(12)) + '.' + QUOTENAME(COALESCE(c.[Column], '%0')) + N' = ''%1''', @IsSelfJoin = @IsSelfJoin | c.IsSelfJoin FROM@Constraints AS c WHEREc.RowID = @ID ELSE SELECT@RowSQL = N' INNER JOIN ' + QUOTENAME(c.[Catalog]) + N'.' + QUOTENAME(c.[Schema]) + N'.' + QUOTENAME(c.[Table]), @RowSQL = @RowSQL + N' AS t' + CAST(@ID AS NVARCHAR(12)) + N' ON t' + CAST(@ID AS NVARCHAR(12)) + N'.' + QUOTENAME(c.[Column]), @pkColumn = QUOTENAME(c.pkColumn), @IsSelfJoin = @IsSelfJoin | c.IsSelfJoin FROM@Constraints AS c WHEREc.RowID = @ID
SELECT TOP 1@ID = c.RowID, @Indent = c.Indent, @RowSQL = @RowSQL + N' = t' + CAST(c.RowID AS NVARCHAR(12)) + N'.' + @pkColumn, @IsSelfJoin = @IsSelfJoin | c.IsSelfJoin FROM@Constraints AS c WHEREc.RowID < @ID AND c.Indent < @Indent ORDER BYc.Indent DESC, c.RowID DESC
INSERT@Stage (Lvl, RowKey) SELECT@Lvl, t.' + QUOTENAME(@pkColumn) + ' FROM' + QUOTENAME(@Catalog) + '.' + QUOTENAME(@Schema) + '.' + QUOTENAME(@Table) + ' AS t INNER JOIN@Stage AS s ON s.RowKey = t.' + QUOTENAME(@Column) + ' AND s.Lvl = @Lvl - 1 LEFT JOIN@Stage AS cr ON cr.RowKey = t.' + QUOTENAME(@pkColumn) + ' WHEREcr.RowKey IS NULL END SELECT ''DELETE FROM ' + QUOTENAME(@Catalog) + '.' + QUOTENAME(@Schema) + '.' + QUOTENAME(@Table) + ' WHERE ' + QUOTENAME(@pkColumn) + ' = '' + QUOTENAME(RowKey, '''''''') FROM @Stage WHERE RowID > 0 ORDER BY RowID DESC'
INSERT@Unwind ( RowID, [SQL] ) VALUES( @RowID, @RowSQL ) END END
INSERT@Return ( RowID, IsSelfJoin, HasPk, [SQL] ) SELECTs.ID, s.IsSelfJoin, s.HasPk, CASE WHEN u.RowID IS NULL THEN s.[SQL] ELSE u.[SQL] END FROM@SQL AS s LEFT JOIN@Unwind AS u ON u.RowID = s.RowID ORDER BYs.ID, u.StepID
I need to find top level node details from xml Execution Plan .
Code :
select distinct mgrCorpID from ( select DISTINCT cd.EmpCorpID, cd.EmpName, cd.mgrCorpID, cd.mgrName ,userrole.ROLE FROM T_Staging_BWDRE_USERROLE AS userrole INNER JOIN T_Staging_BWDRE_USER AS user2 ON userrole.ID = user2.USERROLEID
In a scenario where a developer created a slight modification of a stored procedure because he was afraid of breaking something else and took the easy way out, and a few more later down the line, multiple versions of a stored proc. doing slightly different things are just laying around.
"Last used" would be useful piece of information to determine the most recent date a stored procedure was called, either by the application itself or by another stored procedure itself called by the application.
Any stored proc not used for more than say 6 months would then be identified as a candidate for clean-up.
So - short or creating - after the fact - a trigger to update the usage date upon each call - which means a lot of work and no result for the next six months, how can one go about this ?
DECLARE @Tree TABLE ( NAME VARCHAR(100), [LEVEL] INT ) INSERT INTO @Tree SELECT 'ABCD', 1 UNION SELECT 'ABBBCDD', 2 UNION SELECT 'AABBCCDD', 2 UNION SELECT 'AAAABBBBCCCCDDDD', 3
My question is based on the Level, I want to append that many _(underscores) before the name.
Eg : for level 3 I want the name as ___AAAABBBBCCCCDDDD.
I was thinking to insert this into a temp table and call a while statement based on the number.
I am trying to enable CDC feature in SQL Server 2012 Enterprise Edition ( 11.0.2424.0).The command to enable CDC for Database worked fine, but the command for enabling CDC on Table failed.Command used for enabling CDC on table is as follows.
USE DatabaseName GO EXEC sys.sp_cdc_enable_table @source_schema = N'dbo', @source_name = N'TableName', @role_name = NULL, @supports_net_changes = 1
Following is the error message got
Msg 22832, Level 16, State 1, Procedure sp_cdc_enable_table_internal, Line 623...Could not update the metadata that indicates table [dbo].[TableName] is enabled for Change Data Capture. The failure occurred when executing the command '[sys].[sp_cdc_add_job] @job_type = N'capture''. The error returned was 22836: 'Could not update the metadata for database DatabaseName to indicate that a Change Data Capture job has been added. The failure occurred when executing the command 'sp_add_ jobstep_ internal'. The error returned was 14234: 'The specified '@server' is invalid (valid values are returned by sp_helpserver).'. Use the action and error to determine the cause of the failure and resubmit the request.'. Use the action and error to determine the cause of the failure and resubmit the request.
i have below queries each select is fetching records at one level. Is there a way i can write single query to get to nth level (recursion) instead joining same table 10 times (i don't know in some cases there is may be next level) I stopped at 10th level now. In below example i gave only two levels.
SELECT Distinct a.Col1 AS EmpID, a.Col1 AS EmpID, a.Col2 AS Emp_guid, a.Col2 AS Emp_guid, case
I can easily find user created stat in a databaseSELECT * FROM DB.sys.stats WHERE user_created=1But how do I determine what tables those stats are in? with over 6000 tables I don't feel like looking through all the tables.
There are many duplicate records on my data table because users constantly register under two accounts. I have a query that identify the records that have a duplicate, but it only shows one of the two records, and I need to show the two records so that I can reconcile the differences.The query is taken from a post on stack overflow. It gives me 196, but I need to see the 392 records.
How to identify the duplicates and show the tow records without having to hard code any values, so I can use the query in a report, and anytime there are new duplicates, the report shows them.
In one of my environments, I need to grant the ability to view all the logins and agent jobs to an account, but I don't want to give him "sysadmin" or "securityadmin".
I'm attempting to load some data into an explicit hierarchy in MDS 2012 via the staging table and struggling with the HierarchyName field. Specifically I'm loading data into stg.[Entity Name]_Consolidated and using the exact name of the explicit hierarchy I've set up in the front end web application.
Originally my hierarchy was labelled "Reporting Hierarchy" and when loading the data into staging using this name then running the batch from the Import Data screen I can see the error message "Error - The HierarchyName is missing or is not valid.". I've checked the table mdm.tblHierarchy and can see that the name there is exactly as it was in the staging table and have since renamed the hierarchy as "Reporting_Hierarchy" with the same results.
Our company is a proffesional deticated bullet proof server and general server provider in china. If you're looking for a reliable and long term cooperation bp server provider, it deservers you to read our company file to know more about us.
We have some URLs within a bulk block of text some of which are very long. I need to identify rows where such urls exceed say 100 characters in length in amongst other text.So the rule would be return a record if within the string there is a string (without spaces) longer than 100 characters.
While running SQL Server Profiler I reached some Lock:Escalations. When I searched for Statements having same SPID as Lock:Escalation event I realized that one of delete statements causes this. Is there any way to find out why lock escalation in such place occurres?
Statement is like:
delete from BOOK_IN_LIBRARY where libraryId in (,,,,); <-20 elements ids
I'm trying to find out less than 10% in revenue accounts from a table. Below is a snapshot. Basically, I want to add Revenue mix column in the table using procedure.