LINQ to Entity, joining on NOT IN tables - sql

My brain seems to be mush right now! I am using LINQ to Entity, and I need to get some data from one table that does NOT exist in another table.
For example: I need the groupID, groupname and groupnumber from TABLE A where they do not exist in TABLE B. The groupID will exist in TABLE B, along with other relevant information. The tables do not have any relationship. In SQL it would be quite simply (there is a more elegant and efficient solution, but I want to paint a picture of what I need)
SELECT
GroupID,
GroupName,
GroupNumber,
FROM
TableA
WHERE
GroupID NOT IN (SELECT GroupID FROM TableB)
Is there an easy/elegant way to do this using the Entity Framework/LINQ to Entity?
Right now I have a bunch of queries hitting the db, then comparing, etc. It's pretty messy.

You could use any
var temp =context.TableA
.Where(x=>!context.TableB.Any(y=>y.GroupID!=x.GroupID))
.Select(x=>new { GroupID = x.GroupID, GroupName=x.GroupName, GroupNumber = x.GroupNumber}).ToList();

It depends upon how you've met them, which you don't show, but, generally:
var q = from a in Context.TableA
where !a.Group.TableBs.Any()
select new
{
GroupID = a.GroupID,
GroupName = a.GroupName,
GroupNumber = a.GroupNumber
};

#Nix - Your result set should have been either:
var temp =context.TableA
.Where(x=>context.TableB.Any(y=>y.GroupID != x.GroupID))
.Select(x=>new { GroupID = x.GroupID, GroupName=x.GroupName, GroupNumber = x.GroupNumber}).ToList();
Or
var temp =context.TableA
.Where(x=> ! context.TableB.Any(y=>y.GroupID == x.GroupID))
.Select(x=>new { GroupID = x.GroupID, GroupName=x.GroupName, GroupNumber = x.GroupNumber}).ToList();
But NOT both, like you wrote it.

Related

Move SQL for View Into Manageable Chunks

I have the following code in SQL:
SELECT
(SELECT Form_Title
FROM Forms
WHERE Form_ID = (SELECT TOP 1 Form_ID
FROM [Form_Responses]
WHERE [Form_Response_ID] = [Form_Response_ID])) AS Form_Name
FROM
[FooDb].[dbo].[Submissions]
In essence, I am selecting data three tables "away" and nesting all these selections. So I select a field from one table, and use it to make selection in another.
I can't use vars in a view, so how do I make this remotely readable?
Edit - the pseudocode below is what I was going for with the SQL above and it works, but I don't know how to make it clean, and that's the question:
//Form_Response_ID exists on Submissions
SELECT Get_Query_Result(Form_Response_ID) as Form_Name
FROM Submissions
Get_Query_Result(Form_Response_ID)() {
return SELECT Form_Title FROM Forms WHERE Form_ID = Get_Form_Id(Form_Response_ID);
}
// Form_Responses has Form_Response_ID as well
Get_Form_Id(Form_Response_ID) {
return SELECT TOP 1 Form_ID FROM [Form_Responses] WHERE [Form_Response_ID] = Form_Response_ID
}
Most likely the query you are looking for is like below
select f.Form_Title as Form_Name
from
Forms f JOIN Form_Responses fr
on f.Form_ID=fr.Form_ID
JOIN Submissions s
on fr.Form_Response_ID=S.Form_Response_ID

SQLServer Delete from table with list coming from another table

I have a DELETE requiring a where with an AND in the WHERE clause to pick the rows. One the of values in the WHERE is actually a bunch of ids. I could accomplish with programming to get the list of user ids and then looping using the list.
This query returns a list of GroupUserIds
SELECT Id FROM GroupUser WHERE GroupUserId = #GroupUserId
I this wish to delete from VariableTransaction for each GroupUserId
Foreach #GroupUserId in GroupUserIds
DELETE FROM VariableTransaction WHERE VariableId = #VariableId AND GroupUserId = #GroupUserId
There should be a way to combine these into a single SQL statement but looking at all the examples I cannot figure out a solution, the where with the AND complicates it.
Try using an IN clause with a subquery:
DELETE FROM VariableTransaction WHERE VariableId = #VariableId
AND GroupUserId IN (SELECT Id FROM GroupUser WHERE GroupUserId = #GroupUserId)

delete all the child rows in sql table by parentid

I have a table from which I create a tree with multiple levels and parents. The table structure looks like this.
When I delete the "TitleID", I want all the children and even the grandchildren to be deleted.
What is the easiest way to do such in sql.
If I simple delete with "where ParentID=TitleID", only children with level 1 depth are deleted.
DECLARE #TitleId INT
SELECT ##TitleId = 2
;WITH results AS(
SELECT TitleId
FROM myTable
WHERE TitleId = #TitleId
UNION ALL
SELECT t.TitleId
FROM myTable t
INNER JOIN ret r ON t.ParentID = r.TitleId
)
DELETE FROM myTable WHERE TitleId IN (SELECT TitleId FROM results )
To handle tree structured data in relational database, you can add another column FullID, which contains value like 1.1.3. Then what you need is just a simple where clause WHERE FullID LIKE '1.1.%' if you want to delete node 1.1 and it's children.
The value of FullID can be generated by a stored procedure (for old data), or better by your application (for new data).

Delete category and its children / grandchildren

Using ObjectContext. I'm wanting to do this by passing an SQL query via the ExecuteStoreCommand since I don't fancy retrieving all relevant entities just for the sake of deleting them after.
The Category table is as so:
CatID | CatName | ParentID
Where CatID is the primary key to the ParentID FK
I am wishing to delete a category and also all those that
are under it. Can be 2+ levels deep of sub cats, so different ParentID's
Thought I could do it as below and just set "cascade" on delete option
for the foreign key in the database, but it won't let me and it does not appear to want to
cascade delete down by using the CatID - ParentID relationship and the query gets
stopped by this very FK constraint.
public RedirectToRouteResult DelCat(int CatID)
{
if (CatID != 0)
{
_db.ExecuteStoreCommand("DELETE FROM Categories WHERE CatID={0}", CatID);
_db.SaveChanges();
}
return RedirectToAction("CatManage");
}
Recursive CTE allCategories produces list of all categories in hierarchy. Delete part, obviously, deletes them all.
; with allCategories as (
select CatID
from Categories
where CatID = #CatID_to_delete
union all
select Categories.CatID
from allCategories
inner join Categories
on allCategories.CatID = Categories.ParentID
)
delete Categories
from Categories
inner join allCategories
on Categories.CatID = allCategories.CatID
Try it with select * from allCategories, though, to check first.
There is TEST # Sql Fiddle.
Why not just send two statements in your batch?
DELETE Categories WHERE ParentID = {0};
DELETE Categories WHERE CatID = {0};
If the framework you're using "won't let you" do that, then do this right: put your logic in a stored procedure, and call the stored procedure.

How to get one common value from Database using UNION

2 records in above image are from Db, in above table Constraint are (SID and LINE_ITEM_ID),
SID and LINE_ITEM_ID both column are used to find a unique record.
My issues :
I am looking for a query it should fetch the recored from DB depending on conditions
if i search for PART_NUMBER = 'PAU43-IMB-P6'
1. it should fetch one record from DB if search for PART_NUMBER = 'PAU43-IMB-P6', no mater to which SID that item belong to if there is only one recored either under SID =1 or SID = 2.
2. it should fetch one record which is under SID = 2 only, from DB on search for PART_NUMBER = 'PAU43-IMB-P6', if there are 2 items one in SID=1 and other in SID=2.
i am looking for a query which will search for a given part_number depending on Both SID 1 and 2, and it should return value under SID =2 and it can return value under SID=1 only if the there are no records under SID=2 (query has to withstand a load of Million record search).
Thank you
Select *
from Table
where SID||LINE_ITEM_ID = (
select Max(SID)||Max(LINE_ITEM_ID)
from table
where PART_NUMBER = 'PAU43-IMB-P6'
);
If I understand correctly, for each considered LINE_ITEM_ID you want to return only the one with the largest value for SID. This is a common requirement and, as with most things in SQL, can be written in many different ways; the best performing will depend on many factors, not least of which is the SQL product you are using.
Here's one possible approach:
SELECT DISTINCT * -- use a column list
FROM YourTable AS T1
INNER JOIN (
SELECT T2.LINE_ITEM_ID,
MAX(T2.SID) AS max_SID
FROM YourTable AS T2
GROUP
BY T2.LINE_ITEM_ID
) AS DT1 (LINE_ITEM_ID, max_SID)
ON T1.LINE_ITEM_ID = DT1.LINE_ITEM_ID
AND T1.SID = DT1.max_SID;
That said, I don't recall seeing one that relies on the UNION relational operator. You could easily rewrite the above using the INTERSECT relational operator but it would be more verbose.
Well in my case it worked something like this:
select LINE_ITEM_ID,SID,price_1,part_number from (
(select LINE_ITEM_ID,SID,price_1,part_number from Table where SID = 2)
UNION
(select LINE_ITEM_ID,SID,price_1,part_number from Table SID = 1 and line_item_id NOT IN (select LINE_ITEM_ID,SID,price_1,part_number from Table SID = 2)))
This query solved my issue..........