The following query doesn't seem to work and give syntax error:
update const_acad_record
set const_acad_record.education_level = school_category_type.education_level
FROM school_category_type, sch_rec sch_rec
where const_acad_record.organization_ID = sch_rec.id and
sch_rec.ctgry = school_category_type.code
If I convert this into a sub-query as follows, it works but updates more number of records than required:
update const_acad_record
set education_level = (SELECT education_level
FROM school_category_type sct, sch_rec sr
where const_acad_record.organization_ID = sr.id and
sr.ctgry = sct.code)
(The column education_level comes from table school_category_type.)
You typically need a statement level WHERE clause too, to limit the number of records updated to those with a matching entry. I think that in this example, it can take the form:
UPDATE const_acad_record
SET education_level = (SELECT education_level
FROM school_category_type sct
JOIN sch_rec sr
ON sr.ctgry = sct.code
WHERE const_acad_record.organization_ID = sr.id)
WHERE EXISTS(SELECT education_level
FROM school_category_type sct
JOIN sch_rec sr
ON sr.ctgry = sct.code
WHERE const_acad_record.organization_ID = sr.id)
Untested SQL
This limits the rows update to those for which there is a matching record. In the absence of the statement-level WHERE clause, all rows in the table (const_acad_record) are updated, and those without a matching entry from the SELECT are set to NULL.
If I understood the tables better, I'd probably use an IN clause in the statement-level query, such as:
UPDATE const_acad_record
SET Education_Level = (SELECT education_level
FROM school_category_type sct
JOIN sch_rec sr
ON sr.ctgry = sct.code
WHERE const_acad_record.organization_ID = sr.id)
WHERE Organization_ID IN (SELECT sr.id
FROM school_category_type sct
JOIN sch_rec sr
ON sr.ctgry = sct.code)
Untested SQL
Amongst other issues, it is not clear whether the column education_level comes from the table school_category_type or the table sch_rec; this might alter what's appropriate.
Related
How do I do the below using JOIN:
Select
id_pk, col1, col2,col
From table1 A
Where NOT EXISTS
(select 1 from table2 B
Where A.id_pk = B.id_pk
and A.col1 = B.col1
and A.col2 = B.col2
);
Here, join query cannot be simply used, as we know that both tables share their primary key id_pk, we could rather obtain the primary keys of those records which satisfy the conditions A.id_pk = B.id_pk (Equi-join), A.col1 = B.col1 and A.col2 = B.col2. And we can use this set of primary keys to obtain those records whose primary keys do not match using NOT IN operator. The join query is given as a sub-query, in this case.
Query:
SELECT
id_pk, col1, col2, col
FROM table1
WHERE id_pk NOT IN (
SELECT A.id_pk
FROM table1 A, table2 B
WHERE A.id_pk = B.id_pk
AND A.col1 = B.col1
AND A.col2 = B.col2
);
I am working on sql server I have two tables and I need to return records from the left table which are not found in the right table for that I am using left join like below query,
select #MID=MID,#MName=Name,#PID=PID,#PName=PName,#DID=DID from #CompanyDataInfo where id=#MCount
insert into #temp SELECT Top(1) f.Name,f.PID,f.PName,v.* FROM #CompanyDataInfo f
left join Employee v on v.Id=f.ID and v.DID=f.DID
where v.Id =#MID and v.DId = #DId and v.PId = #PId and v.CId =#CId and DATE_TIME between DATEADD(minute,-555,GETDATE()) and GETDATE() order by DATE_TIME desc
Result should be all rows from #CompanyDataInfo table while no record found in Employee table for related ID, I googled and use "v.Id is null" but not getting expected result
Is there any solution greatly appriciable
Thanks In advance
Your query is not using left join in correct way. You are using your right table reference in where clause. I try to correct it below but I don't have full information about your table schema. Please try this-
select
#MID = MID,
#MName = Name,
#PID = PID,
#PName = PName,
#DID = DID
from #CompanyDataInfo
where id = #MCount
insert into #temp
select
f.Name,
f.PID,
f.PName,
v.*
from #CompanyDataInfo f
left join Employee v on v.Id=f.ID and v.DID=f.DID
where f.Id = #MID and
f.DId = #DId and
f.PId = #PId and
f.CId = #CId and
f.DATE_TIME between DATEADD(minute,-555,GETDATE()) and GETDATE() and
v.Id is null
order by f.DATE_TIME desc
Add ...and v.Id is null to your where clause.
I have two instances of the same database from different days. All tables from one day are called tableA* and from the other tableB*. I would like to compare data to see what have changed. I would like to select all rows that don't match exactly. So for example if one value is different in tables tableA1 and tableB1 I would like to select a corresponding row from table A and mark it as 'new' and from table B and mark it as 'deleted'. I tried with a query like this:
SELECT 'new', ta1.name, ta2.name, ta3.name, ta4.name, ta5.name
FROM tableA1 ta1
LEFT JOIN tableA2 ta2 ON ta1.ta2_id = ta2.id
LEFT JOIN tableA3 ta3 ON ta1.ta3_id = ta3.id
LEFT JOIN tableA4 ta4 ON ta1.ta4_id = ta4.id
LEFT JOIN tableA5 ta5 ON ta5.ta1_id = ta1.id WHERE NOT EXISTS
(SELECT tb1.name, tb2.name, tb3.name, tb4.name, tb5.name
FROM tableB1 tb1
LEFT JOIN tableB2 tb2 ON tb1.tb2_id = tb2.id
LEFT JOIN tableB3 tb3 ON tb1.tb3_id = tb3.id
LEFT JOIN tableB4 tb4 ON tb1.tb4_id = tb4.id
LEFT JOIN tableB5 tb5 ON tb5.tb1_id = tb1.id WHERE
tb1.name = ta1.name AND
tb2.name = ta2.name AND
tb3.name = ta3.name AND
tb4.name = ta4.name AND
tb5.name = ta5.name)
UNION
SELECT 'deleted', tb1.name, tb2.name, tb3.name, tb4.name, tb5.name
FROM tableB1 tb1
LEFT JOIN tableB2 tb2 ON tb1.tb2_id = tb2.id
LEFT JOIN tableB3 tb3 ON tb1.tb3_id = tb3.id
LEFT JOIN tableB4 tb4 ON tb1.tb4_id = tb4.id
LEFT JOIN tableB5 tb5 ON tb5.tb1_id = tb1.id WHERE NOT EXISTS
(SELECT ta1.name, ta2.name, ta3.name, ta4.name, ta5.name
FROM tableA1 ta1
LEFT JOIN tableA2 ta2 ON ta1.ta2_id = ta2.id
LEFT JOIN tableA3 ta3 ON ta1.ta3_id = ta3.id
LEFT JOIN tableA4 ta4 ON ta1.ta4_id = ta4.id
LEFT JOIN tableA5 ta5 ON ta5.ta1_id = ta1.id WHERE
tb1.name = ta1.name AND
tb2.name = ta2.name AND
tb3.name = ta3.name AND
tb4.name = ta4.name AND
tb5.name = ta5.name)
Hoping that if I created the same stuructre and compare all the values I would get the anticipated result. Even if databases are the same I get a lot row selected.
Found the problem. When comparing two NULL values the result is FALSE, the query itself should be fine. So I should have added conditions to check whether values are NULL.
I must be missing something obvious. The orderby cluase in this query has no effect on the order of the items displayed in my select list...
List<String> reps = (from r in db.bookings
where !r.bookingRep1.Contains("*") && !r.bookingRep1.Contains(" ")
orderby r.bookingRep1
select r.bookingRep1).Distinct().ToList();
ViewBag.rep1 = new SelectList(reps, booking.bookingRep1);
the select list...
#Html.DropDownListFor(model => model.bookings.bookingRep1, (SelectList)ViewBag.rep1, "")
I would like the select list to be ordered alphabetically by bookingrep1
Apply ordering after applying Distinct:
List<string> reps =
(from r in db.bookings
where !r.bookingRep1.Contains("*") && !r.bookingRep1.Contains(" ")
select r.bookingRep1).Distinct().OrderBy(rep => rep).ToList();
ViewBag.rep1 = new SelectList(reps, booking.bookingRep1);
When you apply Distinct to ordered query, then ordering just removed from generated SQL:
SELECT
[Distinct1].[bookingRep1] AS [bookingRep1]
FROM ( SELECT DISTINCT
[Extent1].[bookingRep1] AS [bookingRep1]
FROM [dbo].[bookings] AS [Extent1]
WHERE [Extent1].[bookingRep1] NOT LIKE #p1 AND
[Extent1].[bookingRep1] NOT LIKE #p2
) AS [Distinct1]
When ordering is applied after Distinct then its present in generated SQL:
SELECT
[Distinct1].[bookingRep1] AS [bookingRep1]
FROM ( SELECT DISTINCT
[Extent1].[bookingRep1] AS [bookingRep1]
FROM [dbo].[bookings] AS [Extent1]
WHERE [Extent1].[bookingRep1] NOT LIKE #p1 AND
[Extent1].[bookingRep1] NOT LIKE #p2
) AS [Distinct1]
ORDER BY [Distinct1].[bookingRep1] ASC
I am giving here part of the query I am executing:
SELECT SUM(ParentTable.Field1),
(SELECT SUM(ChildrenTable.Field1)
FROM ChildrenRable INNER JOIN
GrandChildrenTable ON ChildrenTable.Id = GrandChildrenTable.ChildrenTableId INNER JOIN
AnotherTable ON GrandChildrenTable.AnotherTableId = AnotherTable.Id
WHERE ChildrenTable.ParentBaleId = ParentTable.Id
AND AnotherTable.Type=1),
----
FROM ParentTable
WHERE some_conditions
Relationships:
ParentTable -> ChildrenTable = 1-to-many
ChildrenTable -> GrandChildrenTable = 1-to-many
GrandChildrenTable -> AnotherTable = 1-to-1
I am executing this query three times, while changing only the Type condition, and here are the results:
Number of records that are returned:
Condition Total execution time (ms)
Type = 1 : 973
Type = 2 : 78810
Type = 3 : 648318
If I execute just the inner join query, here is the count of joined records:
SELECT p.Type, COUNT(*)
FROM CycleActivities ca INNER JOIN
CycleActivityProducts cap ON ca.Id = CAP.CycleActivityId INNER JOIN
Products p ON cap.ProductId = p.Id
GROUP BY p.Type
Type
---- -----------
1 55152
2 13401
4 102730
So, why would the query with Type = 1 condition execute much faster than the query with Type = 2, although it is querying 4x larger resultset (Type is tinyint)?
The way your query is written instructs SQL Server to execute the sub-query with JOIN for every row of the output.
This way it should be faster, if I understand what you want correctly (UPDATED):
with cte_parent as (
select
Id,
SUM (ParentTable.Field1) as Parent_Sum
from ParentTable
group by Id
),
cte_child as (
SELECT
Id,
SUM (ChildrenTable.Field1) as as Child_Sum
FROM ChildrenRable
INNER JOIN
GrandChildrenTable ON ChildrenTable.Id = GrandChildrenTable.ChildrenTableId
INNER JOIN
AnotherTable ON GrandChildrenTable.AnotherTableId = AnotherTable.Id
WHERE
AnotherTable.Type=1
AND
some_conditions
GROUP BY Id
)
select cte_parent.id, Parent_Sum, Child_Sum
from parent_cte
join child_cte on parent_cte.id = child_cte.id