Using multiple resultsets combined with joins in T-SQL - tsql

I'm currently using joins inside my stored procedures for outputting elements from different tables. An aggressive example
select a.*, b.*, c.*, d.*, e.*, f.* from tableA a
join tableB b on a.id = b.foreignid
join tableC c on b.id = c.foreignid
join tableD d on c.id = d.foreignid
join tableE e on d.id = e.foreignid
join tableF f on e.id = f.foreignid
where a.id = 1
It's getting pretty unhandy to work with when mapping the output to entities in my C# code, since I have to maintain a lot of boilerplate code.
Instead I would look into using multiple resultsets, so that I could map each resultset into an object type in code.
But how would I go around achieving this when I my case the different results would all relate to each other? The examples I've been able to find all revolved around selecting from different tables where the data were not related by foreign keys like mine. If I were to ouput my result in multiple resultsets the only thing I can come up with is something like this
select a.* from tableA
where a.id = 1
select b.* from tableB
join tableA a on a.id = b.foreignid
where a.id = 1
select c.* from tableC
join tableB b on b.id = c.foreignid
join tableA on a.id = b.foreginid
where a.id = 1
select d.* from tableD
join tableC c on c.id = d.foreignid
join tableB b on b.id = c.foreignid
join tableA a on a.id = b.foreignid
where a.id = 1
select e.* from tableE
join tableD d on d.id = e.foreignid
join tableC c on c.id = d.foreignid
join tableB b on b.id = c.foreignid
join tableA a on a.id = b.foreignid
where a.id = 1
select f.* from tableF
join tableE e on e.id = f.foreignid
join tableD d on d.id = e.foreignid
join tableC c on c.id = d.foreignid
join tableB b on b.id = c.foreignid
join tableA a on a.id = b.foreignid
where a.id = 1
But this is not cleaner, a lot more ineffecient (I would suppose, since there's alot more join statements)
Is it possible to use multiple resultset in this way I'm trying to? I just don't know how I would write the sql statements in the stored proc without having to do massive joins per resultset as in the example. And with the current solution I get an explosion of columns since I join them all together

You can actually return multiplte resultsets from a single SP and consume them in c#, check this post for instance : http://blogs.msdn.com/b/dditweb/archive/2008/05/06/linq-to-sql-and-multiple-result-sets-in-stored-procedures.aspx
It's a lesser known feature but sounds like what you're asking for. You don't have to join them and return them as a flattend rowset, just get the seperate rowsets and piece them together in memory.
Also you may want to read up on ORM frameworks, that could save you a lot of typing that you coud spend on features if it fits your needs.
https://stackoverflow.com/questions/249550/what-orm-frameworks-for-net-do-you-like-best
Regards GJ

Related

How do you use group by and having clause in EF with parent/child relationship?

How can I write a linq to entities query that includes a group by and a having clause?
For example in SQL:
SELECT * FROM dbo.tblParent p
INNER JOIN
(
SELECT a.ID
FROM dbo.tblParent a
join dbo.tblChild c ON a.ID = c.FkParentID
WHERE a.ColValue = 167
GROUP BY A.ID
HAVING COUNT(c.ID) = 1
) t ON p.ID = t.ID
I found my own answer.
// this is far from pretty but it works as far as I can tell
Apps = (from x in context.tblParents
join t in (
from p in context.tblParents
join c in context.tblChilds
on p.ID equals c.FkParentID
where p.ColValue == 167
group c.ID by p.ID into grouped
where grouped.Count() == 1
select new { grouped.Key }) on x.ID equals t.Key
select x);

sql multiple join (right. left, inner) to mongodb aggregate

//I have a sql like this
SELECT
x.attr1,
p.attr2,
p2.attr3,
o.attr4,
p2.attr5,
a2.attr6
FROM TABLE_O o
RIGHT JOIN TABLE_A a ON a.id = o.id AND a.id2 IS NULL
LEFT JOIN TABLE_A a2 ON a2.id = o.id AND a2.id2 = a.id3
LEFT JOIN TABLE_P p ON a.id4 = p.id4
LEFT JOIN TABLE_P p2 ON a2.id4 = p2.id4
INNER JOIN TABLE_X x ON a.id3 = x.id3
WHERE o.type = 'someText' AND a2.id4
IN ( SELECT id3 FROM TABLE_P WHERE TYPE = "anotherText")
AND x.attr1 = "someText"
//I need an idea about how can i do this on mongo aggregates, thanks.
nosql is a non-relational database type. but The following link may be useful.
mongodb aggregation

How to aggregate calculation in SQL Server?

I have a following script to get the total unit but it gives me an error
Cannot perform an aggregate function on an expression containing an aggregate or a subquery.
Do I need to calculate SUM(ta.Qty) outside the main table?
SELECT
ta.ProductName
, SUM(ta.Total)
, SUM(SUM(ta.Qty) * ta.Unit)
FROM
tableA tA
INNER JOIN
tableB tB on tA.ID = tb.TableAID
INNER JOIN
tableC tc on ta.ID = tc.TableAID
INNER JOIN
tableD td on td.ID = tb.TableBID
GROUP BY
ta.ProductName
Here is a query in the AdventureWorks database that produces the same error (but might make some sense):
SELECT v.Name AS Vendor, SUM(SUM(p.ListPrice*d.OrderQty)+h.Freight)
FROM Production.Product p
INNER JOIN Purchasing.PurchaseOrderDetail d ON p.ProductID = d.ProductID
INNER JOIN Purchasing.PurchaseOrderHeader h ON h.PurchaseOrderID = d.PurchaseOrderID
INNER JOIN Purchasing.Vendor v ON v.BusinessEntityID = h.VendorID
GROUP BY v.Name
And here are two ways that I could rewrite that query to avoid the error:
SELECT v.Name AS Vendor, SUM(x.TotalAmount+h.Freight)
FROM (
SELECT PurchaseOrderID, SUM(p.ListPrice*d.OrderQty) AS TotalAmount
FROM Production.Product p
INNER JOIN Purchasing.PurchaseOrderDetail d ON p.ProductID = d.ProductID
GROUP BY PurchaseOrderID
) x
INNER JOIN Purchasing.PurchaseOrderHeader h ON h.PurchaseOrderID = x.PurchaseOrderID
INNER JOIN Purchasing.Vendor v ON v.BusinessEntityID = h.VendorID
GROUP BY v.Name
SELECT v.Name AS Vendor, SUM(x.TotalAmount+h.Freight)
FROM Purchasing.PurchaseOrderHeader h
INNER JOIN Purchasing.Vendor v ON v.BusinessEntityID = h.VendorID
CROSS APPLY (
SELECT SUM(p.ListPrice*d.OrderQty) AS TotalAmount
FROM Production.Product p
INNER JOIN Purchasing.PurchaseOrderDetail d ON p.ProductID = d.ProductID
WHERE d.PurchaseOrderID=h.PurchaseOrderID
) x
GROUP BY v.Name
The first query uses derived tables and the second one uses CROSS APPLY.

Filter table that I do a LEFT JOIN with

Here's my query at the moment:
SELECT A.*
FROM A
LEFT JOIN B ON B.a_id = A.id
Now, suppose there is a table C which relates directly to B. What I'd like to do is to filter out the records of table B based on C - how do I do that? I've tried placing the filter in the WHERE section:
SELECT A.*
FROM A
LEFT JOIN B ON B.a_id = A.id
LEFT JOIN C ON B.c_id = C.id
WHERE C.id > 10
The problem is that the preceding queryalso filters out table A's results. How do I achieve the result that I want?
you need to put that filter in join :
SELECT *
FROM A
LEFT JOIN
(
SELECT B.*
FROM B
INNER JOIN C ON B.c_id = C.id AND C.id > 10
) AS B ON B.a_id = A.id
it will not filter out the A's results .

Join tables query in SQL Server 2012

I have two tables like below:
TableA --> categoryId(pk), categoryParentId, catName
TableB --> empId(pk), categoryId, empName, empDesignation
I want to get all catName with respective categoryId from TableA where categoryId=2 of TableB is equal to categoryParentId=2 of TableA. Please help.
Result:
1002 SE
1003 MD
Something like this?
SELECT DISTINCT catName FROM TABLEA WHERE categoryParentId IN (SELECT DISTINCT categoryID from TABLEB);
I hope this query will fulfill your need
SELECT TABLEA.CATNAME AS CATEGORY
from TABLEB INNER JOIN TABLEA
ON TABLEA.CATEGORYPARENTID = TABLEB.CATEGORYID
Solution with INNER JOIN:
select TableA.catName
from TableA
inner join TableB on TableA.categoryParentId = TableB.categoryId
Using INNER JOIN is the recommended way to use for joining tables (as opposed to SELECT ... FROM TableA, TableB ...)
See:
INNER JOIN ON vs WHERE clause
(this question was actually about MySql, but the answers say that it's the same for SQL Server)
Difference in INNER join and cartesian join in SQL Server
Answering your comment (I assume that you wanted the categoryId from TableA):
select TableA.catName, TableA.categoryId
from TableA
inner join TableB on TableA.categoryParentId = TableB.categoryId
where TableB.categoryId = 2
another method...
SELECT
catname
from
tablea a INNER JOIN
tableb b ON
a.categoryParentID = b.categoryID
group by
catname
This should do the trick
SELECT tableA.catName
FROM tableA, tableB
WHERE tableB.categoryId = table1.categoryParentId
AND tableB.categoryId = 2;
If you want the unique catNames, you can use
SELECT distinct tableA.catName
FROM tableA, tableB
WHERE tableB.categoryId = table1.categoryParentId
AND tableB.categoryId = 2;