i have these records coming from my stored procedure which i am calling in linq to sql
int_PostTypeId vcr_PostType int_PostTypeId_fk vcr_Slug HLevel
49 c 36 c 1
77 e 49 c/e 2
78 f 77 c/e/f 3
79 g 77 c/e/g 3
i have these set of records.
suppose while editing the int_PostTypeId 49 i changed the slug to c1
1) now the slug in the child records also ought to be changed.
slug in 77 will become c1/e
slug in 78 will become c1/e/f
slug in 79 will become c1/e/g
2) if i edit the record 77 and change the slug to c/e2 then the slug 78 and 79 should also be changed to c/e2/f and c/e2/g.
so editing the slug in the record will change the child slug if exists. what is the most appropriate and efficient way of doing it in linq. i am taking the recursive loop path but i think that is highly inefficient. any idea for more general approach? or any other approach.
If I'm understanding you correctly, you're actually updating a column called vcr_Slug in a record somewhere, rather than building the column's value in your stored procedure. Since you're actually using a stored procedure, why not calculate the column's value? I'm not sure if you're using a recursive common table expression to select your results, but if you are, it could take the form of something like the following (making some assumptions about your table structure which may not, of course, be completely representative):
CREATE FUNCTION dbo.GetPostTypes(#ParentTypeID int)
RETURNS TABLE
AS RETURN
(
WITH CurrentPostTypes(int_PostTypeId, vcr_PostType, int_PostTypeId_fk, vcr_Slug,
HLevel)
AS
(
-- Anchor member definition
SELECT pt.int_PostTypeId, pt.vcr_PostType, pt.int_PostTypeId_fk,
pt.vcr_Slug, 1 AS HLevel
FROM dbo.tblPostTypes AS pt
WHERE pt.int_PostTypeId = #ParentTypeID
UNION ALL
-- Recursive member definition
SELECT pt.int_PostTypeId, pt.vcr_PostType, pt.int_PostTypeId_fk,
cpt.vcr_Slug + '/' + pt.vcr_Slug AS vcr_Slug, cpt.HLevel + 1 AS HLevel
FROM dbo.tblPostTypes AS pt
INNER JOIN CurrentPostTypes AS cpt
ON pt.int_PostTypeId_fk = cpt.int_PostTypeId
)
SELECT *
FROM CurrentPostTypes
)
You'll notice in the recursive member definition where the previous value of vcr_Slug is suffixed with a slash and the current record's column value: cpt.vcr_Slug + '/' + pt.vcr_Slug AS vcr_Slug
Related
I'm investigating an prod issue which has data as below in DB:
11
22
33
44
55
The cursor brings out the active set result in a random order sometimes as below :
44
55
11
22
33
Is this possible and valid?
The only way to make sure that query will return rows in desired order is to - guess what? - use the order by clause.
So:
declare
cursor c1 is
select value
from your_table
order by value; --> this
Anything else is just pure luck (whether you will, or will not, get rows the way you thought you should).
I'm after a bit of guidance here. I have a table that has all the data I need all mixed together in a single column (attributes) like so:
Device Index Attribute index Attributes
5 59 WS020121
5 83 9C-B6-54-A0-41-40
5 90 GROUP\darkwahm
6 59 WS020122
6 83 9D-B8-54-A0-50-40
6 90 GROUP\darkperm
What I am trying to do is split out the data into multiple columns so it will display as:
Device Mac Address User
WS020121 9C-B6-54-A0-41-40 GROUP\darkwahm
WS020122 9D-B8-54-A0-50-40 GROUP\darkperm
After some research I was advised to use the XML path to get these results so I created a query which is:
SELECT cast (av1.attributeValue as varchar(50)) + ','
--cast( av1.attributeValue as varchar(50)) + ','
FROM [dbo].[DeviceAttributes] Av1
WHERE av1.AttributeIndex=59 or av1.AttributeIndex=83 or av1.AttributeIndex=90
FOR XML PATH ('')
This works in the sense of all my data is together but its in a single row all together like this:
WS022743,B0-5A-DA-B4-51-01;60-6D-C7-34-86-05,GROUP\darkwahm,WS022871,D0-27- 88-92-9B-8A,GROUP\securitypc,ABSE-PEARSOND,00-05-9A-3C-78-00;68-F7-28-92-0E-7A,GROUP\SlavinM
Just wondering how I need to tweak the query to get it split across multiple columns and rows like how I mentioned above.
So, according to your query, numbers: 59, 83 and 90 are constants for these rows, if yes, you can try this:
SELECT t1.Attributes as device, t2.Attributes as Mac_Address , t3.Attributes as "user" from
(SELECT Device_Index, Attributes FROM [dbo].[DeviceAttributes] WHERE Attribute_index= 59) t1
INNER JOIN
(SELECT Device_Index, Attributes FROM [dbo].[DeviceAttributes] WHERE Attribute_index = 83) t2
ON t1.Device_Index = t2.Device_Index
INNER JOIN
(SELECT Device_Index, Attributes FROM [dbo].[DeviceAttributes] WHERE Attribute_index = 90) t3
ON t1.Device_Index = t3.Device_Index
I have a table with a column of values with the following sample data that has been pulled for 1 user:
ID | Data
5 Record1
12 NULL
13 NULL
15 Record1
20 Record12
28 NULL
31 NULL
35 Record12
37 Record23
42 Record34
51 NULL
53 Record34
58 Record5
61 Record17
63 NULL
69 Record17
What I would like to do is to delete any values in the Data column where the Data value does not have a start and finish record. So in the above Record 23 and Record 5 would be deleted.
Please note that the Record(n) may appear more than once so it's not as straight forward as doing a count on the Data value. It needs to be incremental, a record should always start and finish before another one starts, if it starts and doesnt finish then I want to remove it.
Sadly SQL Server 2008 does not have LAG or LEAD which would make the operation simpler.
You could use a common table expression for finding the non consecutive (non null) values, and delete them;
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY id) rn FROM table1 WHERE data IS NOT NULL
)
DELETE c1 FROM cte c1
LEFT JOIN cte c2 ON (c1.rn = c2.rn+1 OR c1.rn = c2.rn-1) AND c1.data = c2.data
WHERE c2.id IS NULL
An SQLfiddle to test with.
If you just want to see which rows would be deleted, replace DELETE c1 with SELECT c1.*.
...and as always, remember to back up before running potentially destructive SQL for random people on the Internet.
I have been trying for several days to figure out a solution to this issue but have not been able to come up with an answer. What I have is a data set that looks like this:
Id ParentId Name
16 NULL i_ss_16_Grommets
25 16 ss_25_Grommets
26 NULL inactive_Grommets Clone
27 NULL inactive_Grommets Clone Clone
46 25 ss_46_Grommets
47 46 ss_47_Grommets
48 47 Grommets
What I need to come up with is a function where I can pass an Id and then get the correct Name. The way that I need to find the name involves a sort of reverse hierarchy since it is the youngest child in a branch that will be used. For example, if I pass in Id 46, I need the function to return 'Grommets'. If I pass in Id 47, I need to see 'Grommets', if I pass in Id 26, I would see 'inactive_Grommets Clone' since there are no descendents.
Even though it looks like I could just strip off anything with an underscore after it, I would not be able to since there is no guarantee that the child will be named the same.
Hopefully this makes sense. Any help would be greatly appreciated.
Option with recursive CTE
DECLARE #Id int = 46
;WITH cte AS
(
SELECT Id, ParentId, Name
FROM dbo.test60
WHERE Id = #Id
UNION ALL
SELECT t.Id, t.ParentId, t.Name
FROM dbo.test60 t JOIN cte c ON t.ParentId = c.Id
)
SELECT TOP 1 *
FROM cte
ORDER BY Id DESC
Demo on SQLFiddle
I’m somewhat of a newbie to SQL queries, especially anything containing logic, and although I've searched for hours finding the exact terms to search for is not easy in this case! I have a relatively simple one, I’m sure:
A table has 2 columns, and each row contains data about a function in a program. Some functions have a parent function associated (for grouping). Column A is the unique function ID. Column B indicates, when applicable, the parent function’s ID. All parent function IDs are independent and valid function IDs that exist elsewhere in column A.
For reporting purposes I need to list the functions grouped by their parent ID, listing the parent function with the child functions. I can easily report by parent function ID, but the problem is that a parent function does not know that it is a parent function because its column B is empty!
What I need to do is complete the value in Column B if it is empty and the function is referenced elsewhere as a parent function.
Otherwise stated, for each row that has a null value in Column B:
Take the value from column A
Check for the existence of that value in ANY row on column B
If there is a match, inject the value into column B (so that Column A and B have the same value)
What I have: (Query: SELECT function_id, parent_function FROM functions)
FUNCTION_ID PARENT_FUNCTION
4
13 4
79
138 4
195
314 345
345
What I need to have:
FUNCTION_ID PARENT_FUNCTION
4 4
13 4
79
138 4
195
314 345
345 345
Any Ideas? I can't wait to get more familiar with SQL! Thanks ahead of time.
This should work for you:
UPDATE functions
SET parent_function = function_id
WHERE parent_function IS NULL
AND function_id IN (SELECT parent_function FROM functions)
This will set parent_function equal to function_id where it has not yet been set, and where it appears somewhere in the parent_function column.
If you don't actually want to modify the table data but still return values that you need, you can use similar logic like this:
SELECT f.function_id, COALESCE(f.parent_function, f2.function_id) as parent_function
FROM functions f
LEFT JOIN functions f2
ON f.function_id = f2.function_id
AND f2.function_id IN (SELECT parent_function FROM functions)
maybe you can compare the two table using EXCEPT or INTERSECT
http://msdn.microsoft.com/en-us/library/ms188055.aspx
more tutorials>:
http://www.mssqltips.com/sqlservertip/1327/compare-sql-server-datasets-with-intersect-and-except/
How's this look?
select distinct
t1.funx, t1.parent,
case when t2.parent is null then t1.parent
else t2.parent end as newparent
from
tbl t1 left outer join
tbl t2 on
t1.funx = t2.parent
sqlFiddle