I have 2 tables as below:
Parent child relationship (table 1):
SourceId SourceParentId
1 null
2 1
3 2
4 null
Items (Table 2):
Id SourceId
1 1
2 1
3 2
4 2
5 3
6 4
How to write a linq query that return me all items based on Source ID? If my input is SourceId = 1, i will get items 1,2,3,4 & 5. If my input for sourceId is 2, i will get 3 items: 3, 4 & 5. If my input for sourceID is 4, it will return me item 6. My parent child is N-level and items can appear at any level.
Help :(
Here try this
--Variable to hold input value
DECLARE #inputSourceID INT = 1;
--Recursive CTE that finds all children of input SourceID
WITH MyCTE
AS
(
SELECT SourceID,
SourceParentID
FROM table1
WHERE SourceID = #inputSourceID
UNION ALL
SELECT table1.SourceID,
table1.SourceParentID
FROM table1
INNER JOIN MyCTE
ON table1.SourceParentID = MyCTE.SourceID
)
--Join the CTE with the table2 to find all id
SELECT table2.ID
FROM MyCTE
INNER JOIN table2
ON MyCTE.SourceID = table2.SourceID
Related
I am using this SQL to retrieve hierarchical children count for a comment:
WITH RECURSIVE c AS (
SELECT "Id", "ParentId"
FROM public."Comments"
WHERE "ParentId" = #CommentId
UNION
SELECT s."Id", e."ParentId"
FROM public."Comments" e
INNER JOIN c s ON s."Id" = e."ParentId"
) SELECT COUNT(*)
FROM c;
It works as expected.
But how can I transform this SQL to work with a list of IDs, so it returns a dictionary where KEY is an ID from list in parameters and VALUE is a hierarchical count of children?
I am using this SQL with Dapper in C#
Sample "comments" table:
id | parentId
---------------
1 | null
2 | 1
3 | 2
4 | null
5 | 4
6 | 5
7 | 5
Input:
Array of IDs given to DB
[1, 4]
Output:
Dictionary which has ID from input as key and hierarchical children count as value
{1: 2, 4: 3}
P.S.: the code in input and output is just pseudocode
You can use this query to get the result set
WITH RECURSIVE c AS (
SELECT id, parentId, parentid as sid
FROM Comments
WHERE parentId = ANY(Array [1, 4])
UNION ALL
SELECT e.id, e.parentId, s.sid
FROM Comments e
INNER JOIN c s ON s.id = e.parentId
)
SELECT sid, COUNT(*)
FROM c
group by sid;
returns
sid count
4 3
1 2
I have location data coming from DB. There is parent-Child Relationship in my Location table.
I retrieved the records. But problem is how can I populate my View Model.
For example
Location 'US' has child 'California' and 'New York', and they have their own child.
I am not using any mapping tool.
Here is the sample data
Id ChildId Name
1 null US
2 null Canada
3 1 California
4 3 Los Angeles
5 2 Nova Scotia
6 5 Halifax
And I dont know the depth of my Location table's parent-Child relation ship
I like some solution so when I write
List<LocVM> obj=context.locations.select(w=new LocVM{....,ChileLocation=w.ChildLoc}).tolist();
so my object will have all locations and child locations
View Model
Class LocVM{
public int Id{get;set;}
public int chileId {get;set;}
public LocVM ChildLocations {get;set;}
}
So with query above
Any idea is welcome
Sample Data
IF OBJECT_ID('dbo.SampleData') IS NOT NULL
DROP TABLE SampleData
CREATE TABLE SampleData (ID int,ChildId INT,Name VARCHAR(20))
INSERT INTO SampleData
SELECT 1,null,'US' UNION ALL
SELECT 2,null,'Canada' UNION ALL
SELECT 3,1 ,'California' UNION ALL
SELECT 4,3 ,'Los Angeles' UNION ALL
SELECT 5,2 ,'Nova Scotia' UNION ALL
SELECT 6,5 ,'Halifax'
SELECT * FROM SampleData
This Recursive CTE May be able to solve your requirement.
;With Cte
AS
(
SELECT
ID
,ChildId
,CAST('/'+Name AS nvarchar(1000)) AS [Heirarchy]
FROM SampleData
WHERE ChildId IS NULL
UNION ALL
SELECT
e.ID
,e.ChildId
,CAST([Heirarchy]+'/'+e.Name AS nvarchar(1000)) AS [Heirarchy]
FROM SampleData e
INNER JOIN Cte t
ON t.ID = e.ChildId
)
SELECT ID
,RIGHT([Heirarchy],LEN([Heirarchy])-1) AS [CityHeirarchyPath]
FROM Cte
Result
ID CityHeirarchyPath
----------------------
1 US
2 Canada
5 Canada/Nova Scotia
6 Canada/Nova Scotia/Halifax
3 US/California
4 US/California/Los Angeles
Sorry I am really a newbie into programming and I am trying to merge two different columns into one column using sql but if it is not possible can it be done using sql code in c#?
I have two tables Product1 and Product2, these tables both have CatID.
For Product1, the CatID contains
1
2
3
For Product2, the CatID contains
1
2
3
4
5
The results that I am getting using union is if they have both similar id it will be merge into one and using concat it will duplicate into like
1 1
2 2
3 3
4
5
But the results that I want is the 1 to 3 is from product1 and then the 4 to 8 from product2 like it will continue on counting with no duplicate:
1
2
3
4
5
6
7
8
Is this possible?
Try it like this:
SELECT CatID, ...OtherColumns...
FROM Product1
UNION SELECT CatID, ...OtherColumns...
FROM Product2
WHERE Product2.CatID NOT IN(SELECT CatID FROM Product1)
ORDER BY CatID
(test here: http://sqlfiddle.com/#!9/7887c):
CREATE TABLE T1(ID INT, txt VARCHAR(10));
INSERT INTO T1 SELECT 1, 'test A'
UNION SELECT 2, 'test B'
UNION SELECT 3, 'test C';
CREATE TABLE T2(ID INT, txt VARCHAR(10));
INSERT INTO T2 SELECT 1, 'test 1'
UNION SELECT 2, 'test 2'
UNION SELECT 3, 'test 3'
UNION SELECT 4, 'test 4'
UNION SELECT 5, 'test 5';
SELECT ID, txt
FROM T1
UNION SELECT ID, txt
FROM T2
WHERE T2.ID NOT IN(SELECT ID FROM T1)
ORDER BY ID
The result:
ID txt
1 test A
2 test B
3 test C
4 test 4
5 test 5
I am not sure what you want but with LINQ you can create a select. If you show us the SQL code it would be very helpful.
can you try this query, use union
select * from Product1
union
select * from Product2 NOT IN(SELECT CatID FROM Product1)
I have the following table
CamId RegNumber DateSeen
5 G1234B 18/02/2014 11:54
3 G1234B 18/02/2014 11:51
5 G11854 18/02/2014 11:50
3 G11854 18/02/2014 11:49
3 G24581 18/02/2014 11:48
5 G24581 18/02/2014 11:47
I would like to retrieve all records with CamId 3 that do not have a later entry in CamId 5 based on the dateseen entry on CamId 3 for that particular reg number.
From the sampe data table above the system should return just one number plate G24581 as it has no later entries in CamId 5.
One method you can employ is to join onto the table twice so that in one table you have the values where CamID is 3 and the other is 5. Then you would want to get all records from the first table that do no have a record in the second table.
Select A.* from Table A
LEFT JOIN ( Select * from Table ) B on A.RegNumber = B.RegNumber AND A.CamID = 3 and B.CamID = 5 AND A.DateSeen <= B.DateSeen
WHERE B.CamID IS NULL
Try this:
var query = from r1 in db.Regs
where r1.CamId == 3 &&
!db.Regs.Any(r2 => r2.CamId==5 && r2.DateSeen>r1.DateSeen && r2.RegNumber==r1.RegNumber)
select r1;
I have following table structures.
**Table_A**
A_Id(BigInt) Category_Ids(varchar(50))
1 1,2,3
2 2,3
**Table_B**
B_Id(BigInt) C_Id(Bigint) Name(varchar(50))
1 2 A
2 1 C
3 3 B
First Query:
In this query want to get the record where A_Id=1. I have executed following code.
Select [Category_Ids] from Table_A where A_Id=1
This returns the data table with single column and single row with values “1, 2, 3”
Assume that above query fills the data into the A_datatable. I get the string from following code.
String ids = A_datatable.column[0][“Category_Ids”];
Second Query:
Now, I have to fetch the values from Table_B where C_Id in (1, 2, 3). I have executed following code and passed the string value to following query.
Select * from Table_B where C_Id in (ids)
When I execute above query getting the error, failed to convert parameter value from a String to a Int64.
You can actually do it in a single query.
SELECT b.*
FROM Table_A a
INNER JOIN Table_B b
ON ',' + a.Category_IDs + ',' LIKE '%,' + CAST(C_ID AS VARCHAR(10)) + ',%'
WHERE a.A_ID = 1
Caveat: This query is an index-killer. You should have properly normalize your tables.
UPDATE 1
Suggested Schema Design,
Table_A
A_ID
Category_ID
Table_C
B_ID
C_ID
Name
Records
Table_A
A_ID Category_ID
1 1
1 2
1 3
2 4
2 5
Table_B
B_Id C_Id Name
1 2 A
2 1 C
3 3 B
You can use a string splitter function like the one described here http://www.sqlservercentral.com/articles/Tally+Table/72993/
scroll down to the 'CREATE FUNCTION' script and run it to create your function, then you can split the comma separate string for use in your 'where in' clause
select * from Table_B
where C_Id in (select item from dbo.DelimitedSplit8K(IDS,','))