How to do recursive query using a temporary table in Mysql - c#

OrganisationID OrganisationName parentID
1 Org1 Null
2 Org2 1
3 Org3 1
4 Org4 2
5 Org5 2
6 Org5 4
Table Name is tbl_Organisation
I am having a table similar to this. All I am trying is to retreive the Sub Organisation and display it. Suppose the Org ID passed is 3, then the Org3 doesnt have any child so it displays only Org3. Suppose if OrgID =2 then the Org2 has a child Org4 and Org4 has a child Org5. So for OrgID=2 I have to display Org2, Org4 and Or5. SO how can I do that. I have tried few things but it didn't work as I intended.
SELECT distinct b.OrganisationID,b.OrganisationName
FROM tbl_organisation as a LEFT OUTER JOIN tbl_organisation as b
on a.OrganisationID=b.ParentID where a.OrganisationID=b.parentID
Tell me where I am wrong
I am using this in asp.net website, I am using c# and mysql

This is related to Hierarchail Query:
SELECT (LPAD(' ', level * 3, ' ')||OrganisationID) as Org_id,
OrganisationName,
parentID,
LEVEL
FROM tbl_Organisation
START WITH OrganisationID = ---
Comment: Pass the Organisation ID here
CONNECT BY PRIOR OrganisationID = parentID
If you pass 1 as the OrganizationID then the Output will be
Org_id OrganisationName parentID LEVEL
1 Org1 1
2 Org2 1 2
4 Org4 2 3
6 Org6 4 4
5 Org4 2 3
3 Org2 1 2

Related

Problems in Right join in SQl

I have the following table structure also i have mention my expected output
please help me with query as i dont know much about sql query
Table Structure
Table 1 : Emp Details
FName Id
Pratik 1
Praveen 3
Nilesh 2
Table 1 : JoinigDocument
id DocumentName
1 Leaving
2 Exp letter
3 birth cert
Table 2 : EmployeeJoiningDocument
EmpId JoiningDocumentId
1 1
1 2
3 1
3 2
3 3
2 1
2 3
Expected Output :
FName Id JoiningDocumentId DocumentName
Pratik 1 1 Leaving
Pratik 1 2 Exp letter
Pratik 1 null birth cert
Praveen 3 1 Leaving
Praveen 3 2 Exp letter
Praveen 3 3 birth cert
Nilesh 2 1 Leaving
Nilesh 2 null Exp letter
Nilesh 2 3 birth cert
You can write a query as:
select
A.FName,
A.Id,
B.JoiningDocumentId,
c.DocumentName
from #JoinigDocument C
cross join #EmployeeDetail A
Left join #EmployeeJoiningDocument B on B.EmployeeId = A.id and
B.JoiningDocumentId = C.id
order by A.Id
First cross join JoinigDocument and EmployeeDetail table so that you get all possible combinations of Employee and Documents irrespective of the fact that employee has that Joining Document or not. Then you need to do a left join to retain all these matches and find data corresponding to valid entries in EmployeeJoiningDocument.
Demo

SQL query to get matching records from Table1 and Table2 with a custom column showing 1/0 if data is present

I have several table related to multilingual Photo Galley like
AlbumCategories
AlbumName
Photos
PhotoDetails
Sample Table Structure of two table. I actually want a result set that will show me list of all records from Photos Table for particular AlbumID along with a custom column that will show TRUE or FALSE based on if particular PhotoID is present in the PhotoDetails Table
Table: Photos
PhotoID PhotoFile AlbumID
1 Photo1.jpg 7
2 Photo2.jpg 7
3 Photo3.jpg 5
4 Photo4.jpg 5
5 Photo5.jpg 7
6 Photo6.jpg 7
Table: PhotoDetails
PDID PhotoID PDTitle AlbumID LanguageID
11 1 Photo 1 7 1
22 2 Photo 2 7 1
33 3 Photo 3 5 1
44 4 Photo 4 5 1
DESIRED OUT PUT
PhotoID PDTitle AlbumID DetailPresent
1 Photo1 7 TRUE
2 Photo2 7 TRUE
5 Photo5 7 FALSE
6 Photo6 7 FALSE
I tried something several JOIN based queries but could not get the desired result
SELECT pd.PhotoTitle, p.PhotoTN,p.PhotoCreatedOn, pd.AlbumID, ISNULL(p.PhotoID,NULL) AS Missing FROM AlbumPhotos p
JOIN AlbumPhotoDetails pd
ON p.PhotoID = pd.PhotoID WHERE pd.AlbumID = 16
This query gives me the same result
SELECT pd.PhotoTitle, p.PhotoTN,p.PhotoCreatedOn, pd.AlbumID, ISNULL(p.PhotoID,NULL) AS Missing FROM AlbumPhotos p
JOIN AlbumPhotoDetails pd
ON p.PhotoID = pd.PhotoID WHERE pd.AlbumID = 16
OR p.PhotoID IN (SELECT PhotoID FROM AlbumPhotoDetails WHERE LanguageID = 1 AND AlbumID = 16)
Above query get me the result of matching based on PhotoID. I am lost how i can actually achieve the desired result as shown in the above sample 'DESIRED OUT PUT`
Use a left outer join.
The table examples that you have shown doesn't make any sense, as there is no field to connect them, and the PDTitle values that you want in the result doesn't exist in the example data.
Assuming that there is a PhotoId field in the PhotoDetails table (like in the AlbumPhotoDetails table that you use in the query that you show), and that the PhotoDetails table contains the titles that you want in the result, you can do like this:
select
p.PhotoId, d.PDTitle, p.AlbumId,
case when d.PhotoId is null then 'FALSE' else 'TRUE' end
from Photos p
left join PhotoDetails d on d.PhotoId = p.PhotoId
where p.AlbumId = 7
Note that the title will be null where there are no corresponding record in the PhotoDetails table.

Subquery getting the parent addedby field

Im trying to create a field called Owner in my table where You select the AddedBy field where parentID is equal to the PostID so far it only prints out the first field and the second is always null. Im doing a subquery on a query. Im trying to get the parent AddedBy field
SELECT Level, Sequence, PostID, AddedBy, Title, ParentID, Path_String,
CASE WHEN ParentID IS NULL THEN
AddedBy
ELSE
(SELECT AddedBy FROM cte o WHERE o.PostID = ParentID)
END AS Owner
FROM cte order by Sequence
Im trying to get a count of all posts that related to the PostID joinded by ParentID in a join but im getting an error so when i do a group by of all the Fields i still get the error:- error is below
SELECT s.Level, s.Sequence, s.PostID, s.AddedBy,
s.Title, s.ParentID, s.Path_String,
Owner = COALESCE(o.AddedBy, s.AddedBy), COUNT(r.ParentID)
FROM cte AS s
LEFT OUTER JOIN cte AS o
ON s.ParentID = o.PostID
RIGHT join cte AS r
on s.PostID = r.ParentID
ORDER BY s.Sequence;
i get the following error:
Msg 8120, Level 16, State 1, Procedure sproc_GetPostsByThread, Line 34
Column 'cte.Level' is invalid in the select list because it is not
contained in either an aggregate function or the GROUP BY clause.
PostID, ParentID, AddedBy, Title, Path_String:- PostID is IdentityColumn Path_String is in this format 1/, 1/1/, 1/1/2 and ParentID is an integer
Level Sequence PostID AddedBy Title ParentID Path_String Owner Count
1 00000003 3 kirkdm test NULL 3/ kirkdm 1
2 0000000300000005 5 MikeDM re: test 3 3/5/ kirkdm 2
3 000000030000000500000008 8 Joelene re: test 5 3/5/8/ MikeDM 2
3 000000030000000500000009 9 kirkdm re: test 5 3/5/9/ MikeDM 1
4 00000003000000050000000900000010 10 Crushanin re: test 9 3/5/9/10/ kirkdm 1
Should be this
Level Sequence PostID AddedBy Title ParentID Path_String Owner Count column here
1 00000003 3 kirkdm test NULL 3/ kirkdm
2 0000000300000005 5 MikeDM re: test 3 3/5/ kirkdm
3 000000030000000500000008 8 Joelene re: test 5 3/5/8/ MikeDM
4 00000003000000050000000800000014 14 Christian re: test 8 3/5/8/14/ Joelene
4 00000003000000050000000800000015 15 Zeke re: test 8 3/5/8/15/ Joelene
3 000000030000000500000009 9 kirkdm re: test 5 3/5/9/ MikeDM
4 00000003000000050000000900000010 10 Crushanin re: test 9 3/5/9/10/ kirkdm
5 0000000300000005000000090000001000000011 11 Tim re: test 10 3/5/9/10/11/ Crushanin
SELECT s.Level, s.Sequence, s.PostID, s.AddedBy,
s.Title, s.ParentID, s.Path_String,
Owner = COALESCE(o.AddedBy, s.AddedBy)
FROM cte AS s
LEFT OUTER JOIN cte AS o
ON s.ParentID = o.PostID
ORDER BY s.Sequence;

How to add a Restriction to an inner join?

I have the following NHibernate DetatchedCriteria,
return DetachedCriteria.For<MMFund>()
.CreateCriteria<MMFund>(x => x.DataUniverse)
.Add<DataUniverse>(x => x.SiteId == 100)
.SetProjection(LambdaProjection.Property<MMFund>(x => x.FundId));
which is producing the following SQL:
and
this_.ShareClassReturn_ShareClassId in
(
SELECT f.[Fund_ID] as y0_
FROM
dbo.Fund f inner join CAP.DataUniverse du
on f.[Fund_TypeID] = du.[DataUniverse_TypeId]
and f.[Fund_CountryID] = du.[DataUniverse_CountryID]
WHERE fu.[DataUniverse_SiteId] = 100
)
There are many funds in a DataUniverse.
I need to filter this so that I can select only the funds with a country ID of 'ET', so that my query looks as follows:
and
scr.ShareClassReturn_ShareClassId in
(
/* Get funds in universe */
SELECT f.[Fund_ID] as y0_
FROM dbo.Fund f inner join CAP.DataUniverse du
on f.[Fund_TypeID] = du.[DataUniverse_TypeId]
and f.[Fund_CountryID] = 'ET' // these are the guys I need
WHERE du.[DataUniverse_SiteId] = 100
)
However, I'm not sure what I need to do to the DetachedCriteria in order to make this happen. The problem I'm having is that no matter what I do, it's putting the clause in the wrong place, such as
WHERE du.[DataUniverse_SiteId] = 100 and f.Fund_CountryId = 'ET'
when I add the line .Add(Restrictions.Eq("CountryId", "ET")) as follows
return DetachedCriteria.For<MMFund>()
.Add(Restrictions.Eq("CountryId", "ET"))
.CreateCriteria<MMFund>(x => x.DataUniverse)
.Add<DataUniverse>(x => x.SiteId == 100)
.SetProjection(LambdaProjection.Property<MMFund>(x => x.FundId));
or it attempts to filter on the wrong table entirely when I specify that the Restriction should be part of the second .CreateCriteria, such as
return DetachedCriteria.For<MMFund>()
.CreateCriteria<MMFund>(x => x.DataUniverse)
.Add(Restrictions.Eq("CountryId", "ET"))
.Add<DataUniverse>(x => x.SiteId == 100)
.SetProjection(LambdaProjection.Property<MMFund>(x => x.FundId));
which produces this;
WHERE du.[DataUniverse_SiteId] = 100 and du.[DataUniverse_CountryID] = 'ET'
** note - as I'm using the Criteria API, this is actually the Restriction that I'm using:
.Add<MMFund>(f => f.CountryId == "ET")
I used the Restriction terminology because it's more explicit to what I'm trying to achieve. The Criteria API & the other way both produce the exact same results.
Why do you think Where is the wrong place for the filter? That's where filtering happens.
The generated SQL looks sound. You have two tables joined on their common fields. The Where clause is providing the appropriate filtering information. If your preferred SQL statement was in place, you'd have data joined on TypeID alone, not the CountryID.
For example, let's say your Fund table looks like this
TypeID CountryID
1 1
1 2
2 1
2 2
3 1
4 1
And your DataUniverse table is the following
TypeID CountryID
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
4 1
4 2
If you wrote SQL like you desire, you would produce a join based on TypeID and you would filter Fund.CountryID = 1, for example. What would your product look like?
F.TypeID F.CountryID D.TypeID D.CountryID
1 1 1 1
1 1 1 2
1 1 1 3
2 1 2 1
2 1 2 2
2 1 2 3
3 1 3 1
3 1 3 2
4 1 4 1
4 1 4 2
Is that your desired output? Yes, you've filtered Fund.CountryID, but your join was just on TypeID, so you've got all records from DataUniverse with that matching type for each Fund.
With the join on the two fields and the Where filtering the CountryID, the result will be the following
F.TypeID F.CountryID D.TypeID D.CountryID
1 1 1 1
2 1 2 1
3 1 3 1
4 1 4 1
The question is which set of data is the one you expect?

SQL Server version of Oracle's CONNECT BY in LINQ to show hierachy

I have successfully simulated an Oracle CONNECT BY statement in SQL Server 2008 by following these 2 previous answers here and here and adjusting to get the results I need. But how do I do this in LINQ?
Here is an example of what I am doing using a dummy database:
CREATE TABLE Employee(
EmployeeID INT IDENTITY(1,1) PRIMARY KEY,
Department INT NOT NULL,
EmployeeName VARCHAR(40) NOT NULL,
PeckingOrder INT NOT NULL,
HigherDepartment INT NULL)
INSERT INTO Employee (Department,EmployeeName,PeckingOrder,HigherDepartment)
VALUES (1,'Bart',1,NULL),(2,'Homer',1,1),(2,'Marge',2,NULL),
(3,'Lisa',1,2),(3,'Maggie',2,2),(3,'Santas Helper',3,1)
EmployeeID Department EmployeeName PeckingOrder HigherDepartment
1 1 Bart 1 NULL
2 2 Homer 1 1
3 2 Marge 2 NULL
4 3 Lisa 1 2
5 3 Maggie 2 2
6 3 Santas Helper 3 1
and this is the SQL used to return the heirachy:
WITH n(level, PeckingOrder, Department, EmployeeName, HigherDepartment) AS
(SELECT 1, PeckingOrder, Department, EmployeeName, HigherDepartment
FROM Test.dbo.Employee
WHERE Department = 3
UNION ALL
SELECT n.level + 1, nplus1.PeckingOrder, nplus1.Department, nplus1.EmployeeName, nplus1.HigherDepartment
FROM Test.dbo.Employee as nplus1
JOIN n ON n.HigherDepartment = nplus1.Department)
SELECT MAX(level) AS level, PeckingOrder, Department, EmployeeName, HigherDepartment
FROM n
GROUP BY PeckingOrder, Department, EmployeeName, HigherDepartment
ORDER BY MAX(level) DESC, PeckingOrder ASC
level PeckingOrder Department EmployeeName HigherDepartment
3 1 1 Bart NULL
2 1 2 Homer 1
2 2 2 Marge NULL
1 1 3 Lisa 2
1 2 3 Maggie 2
1 3 3 Santas Helper 1
You could use ExecuteQuery:
class YourRow
{
public int level {get; set;}
public int PeckingOrder {get; set;}
...
}
using (var db = new LinqDataContext())
{
var list = db.ExecuteQuery<YourRow>(
#"
WITH n(level, PeckingOrder, Department, EmployeeName, HigherDepartment) AS
(SELECT 1, PeckingOrder, Department, EmployeeName, HigherDepartment
...
";
}
Or perhaps better, create a view that contains the query, and use LINQ to read from the view.

Categories

Resources