I am going to update a table using the sum of specific value from 3 different tables. For this purpose I wrote this query. But it takes too much time, what is the most efficient query for this purpose?
UPDATE dbo.dumpfile_doroud
SET dumpfile_doroud.sms_count_on_net = (SELECT sms_count_on_net
FROM dbo.dumpfile139201
WHERE
dbo.dumpfile_doroud.msisdn = dbo.dumpfile139201.msisdn)
+ (SELECT sms_count_on_net
FROM dbo.dumpfile139202
WHERE
dbo.dumpfile_doroud.msisdn = dbo.dumpfile139202.msisdn)
+ (SELECT sms_count_on_net
FROM dbo.dumpfile139203
WHERE
dbo.dumpfile_doroud.msisdn = dbo.dumpfile139203.msisdn)
P.S: dumpfile_doroud is small table but other three tables are really big.
Try this:
UPDATE t1
SET t1.sms_count_on_net=isnull(t2.sms_count_on_net,0) +
isnull(t3.sms_count_on_net,0) +
isnull(t4.sms_count_on_net,0)
FROM dbo.dumpfile_doroud t1
LEFT JOIN dbo.dumpfile139201 t2
ON t2.msisdn = t1.msisdn
LEFT JOIN dumpfile139202 t3
ON t3.msisdn = t1.msisdn
LEFT JOIN dumpfile139203 t4
ON t4.msisdn = t1.msisdn
I don't think it's possible to make faster query, so you can try put indexes. I think you can create nonclustered index on column msisdn on all tables. Syntax:
CREATE NONCLUSTERED INDEX IX_doroud_dumpfile139201
ON dbo.dumpfile139201(msisdn);
You can run SQL Management studio and turn on display estimated execution plan this sometimes gives good advices on creating indexes.
Create a subquery to calculate the totals then join the table to it
UPDATE o
SET o.sms_count_on_net = n.sms_count_on_net
FROM
dbo.dumpfile_doroud o
JOIN
(SELECT
d.msisdn, sms_count_on_net = (d1.sms_count_on_net+d2.sms_count_on_net+d3.sms_count_on_net)
FROM
dbo.dumpfile_doroud d
LEFT JOIN dbo.dumpfile139201 d1 ON d1.msisdn = d.msisdn
LEFT JOIN dbo.dumpfile139202 d2 ON d2.msisdn = d.msisdn
LEFT JOIN dbo.dumpfile139203 d3 ON d3.msisdn = d.msisdn) n
ON o.msisdn = n.msisdn
Note that if the value is missing from any of those tables the total will be null. That may or may not be what you want
Related
I am trying to pair 2 tables (nicknamed PERSIP and ECIF) on their ID field, (labeled TABLE1 & TABLE2) to create a RESULTTABLE, where the ym_id (for both tables) variable is set to my timekey0 variable for a specific datetime.
I am wondering why this code produces 0 rows of resulting data. After looking online, this was the format people posted as solutions to similar problems.
%let timekey0 = 202110;
proc sql;
CREATE TABLE RESULTTABLE AS
SELECT
PERSIP.col1,
PERSIP.col2,
PERSIP.col3,
ECIF.col1,
ECIF.col2,
ECIF.col3,
ECIF.col4
FROM DB.TABLE1 PERSIP
LEFT JOIN DB.TABLE2 ECIF
ON PERSIP.ID = ECIF.ID
WHERE ECIF.ym_id = &timekey0.
AND PERSIP.ym_id = &timekey0.;
quit;
I got a result of 0 rows with many columns. Not sure if my join type is incorrect but I have 0 rows in the table.
There may be two reasons for this:
There is no records matching to your where criteria (ECIF.ym_id = &timekey0.
AND PERSIP.ym_id = &timekey0.)
There is no records to join matching your on criteria (ON PERSIP.ID = ECIF.ID)
Your logic seems off. You say you want a LEFT JOIN then use a variable from the "RIGHT" table in your WHERE condition.
Most likely you just want to add those conditions to the ON condition.
FROM TABLE1 PERSIP
LEFT JOIN TABLE2 ECIF
ON PERSIP.ID = ECIF.ID
AND ECIF.ym_id = &timekey0.
AND PERSIP.ym_id = &timekey0.
Or perhaps just keep the condition that will limit the observations read from the "LEFT" table in the WHERE condition
FROM TABLE1 PERSIP
LEFT JOIN TABLE2 ECIF
ON PERSIP.ID = ECIF.ID
AND PERSIP.ym_id = ECIF.ym_id
WHERE PERSIP.ym_id = &timekey0.
My goal here is to combine the joint name, type 1 (Ex.1), to its primary account (Ex.2). This should be done for each share.
Should I be creating a temporary table to merge them into? I'm using SQL Server 2014
Something like this:
select t1.account,
t1.primename,
t2.primename,
t1.shareid,
t1.sharedesc
from table t1
left join table t2 on t1.account = t2.account and
t1.shareid = t2.shareid and
t1.nametype = 0 and
t2.nametype = 1
where t1.nametype = 0
To get your data, you'll need a query similar to this one. I'm guessing at the keys on your table, though.
SELECT
Ex1.*, Ex2.JointName
FROM
Ex1 LEFT JOIN Ex2 ON Ex1.Account = Ex2.Account
AND Ex1.ShareDesc = Ex2.ShareDesc
AND Ex1.ShareID = Ex2.ShareID
AND Ex1.NameDesc = 'Joint'
This will return a result set that you can use where you need to. You can wrap this in a view, which will then act like a table and always be up to date, if you need to.
I have two tables. I want to update one with another.
I have written two queries to show you the result. Here are my two queries
select PrjTermsID,InstNo,InstDesc,BlockID from ProjectPaymentTerms where BlockID=1
select PlotBookingID,InstNo,InstDesc,PrjTermsID from PlotPaymentTerms where PlotBookingID in
( select PlotBookingID from PlotBooking where PlotID in ( select PlotID from PlotMaster where AppartmentBlock=1))
and see the image for results
First table has 1 to 13 records with InstNo and second table has each PlotBookingID has 13 records.(Each plot will have 13(all) payment terms right?). Now I want to update the second table PlotPaymentTerms with first table autogenerated Id. IF I try with Inner join it is giving more results. How can I write update query to update the second table?
update ppt
set ppt.PrjTermsID = pp.PrjTermsID
from PlotPaymentTerms ppt
inner join ProjectPaymentTerms pp on ppt.InstNo = pp.InstNo and ppt.BlockID = 1
inner join PlotBooking pb on ppt.PlotBookingID = pb.PlotBookingID
inner join PlotMaster pm on pb.PlotID = pm.PlotID
where pm.AppartmentBlock = 1
please check this.
I don't think it is the right way to do. Anyways it works for me.
update ppt set ppt.PrjTermsID = pp.PrjTermsID from PlotPaymentTerms ppt
inner join ProjectPaymentTerms pp on ppt.InstNo = pp.InstNo and pp.BlockID=1
and ppt.PlotBookingID in(select PlotBookingID from PlotBooking where PlotID in ( select PlotID from PlotMaster where AppartmentBlock=1))
Thnaks to #Mukund
I'm replacing a subquery with an self join to improve performance of my query.
The old subquery was like this:
(SELECT fage2.agecat
FROM people AS fage2
WHERE fage2.aacode = people.aacode
AND fage2.persno = 2) AS RAge2,
The new self join is like this:
(SELECT [People].[AgeCat]
FROM [People]
INNER JOIN [People] AS p2
ON [People].[aacode] = [P2].[aacode]
WHERE [P2].[PERSNO] = 2 ) AS RAge2,
but returns a No Current Record error message.
The goal is to find the record that has the same aacode but has the PERSNO number of 2 and return the AgeCat for that record in a column called RAge2,
This is only part of a larger query which is explained in full Convert a SQL subquery into a join when looking at another record in the same table Access 2010
Huum, looks like this query that you want to optimize is part of a bigger query, and would be important to the question that you post the entire query so it would help on understanding your problem ...
Also, from what I can see you would be showing the RAge2 for both rows with same AACode not only to the one that has Persno = 2 as you said on the goal. Pasting your entire query would help to understand that also.
I was trying to understand your query, so I created a fake query for your original one:
SELECT
(SELECT FAge2.AgeCat
FROM People AS FAge2
WHERE FAge2.aacode = People.aacode
AND FAge2.PERSNO = 2) AS RAge2,
People.PersonId
FROM People
To get the same results you would need a Left Join and not a Inner Join as a query with a subquery wouldn't exclude results from the outer table, so you would have something like this as the resulting Join query:
SELECT
FAge2.AgeCat as RAge2,
People.PersonID,
FROM People
Left JOIN People AS FAge2 ON (FAge2.aacode = People.aacode AND FAge2.PERSNO = 2)
Please use:
(SELECT [People].[AgeCat] FROM [People] INNER JOIN [People] AS P2 ON ([People].[aacode] = [P2].[aacode] AND [P2].[PERSNO] = 2)) AS RAge2
I have a query I turned into a view that works OK. But the site_phrase sp table seems to be not using a column and goes through all the records in the table. Why is that? Here is the query:
EXPLAIN SELECT
`p`.`id` AS `id`,
`p`.`text` AS `phrase`,
`p`.`ignored` AS `ignored_phrase`,
`p`.`client_id` AS `client_id`,
`s`.`id` AS `site_id`,
`s`.`sub_domain` AS `sub_domain`,
`s`.`competitor` AS `competitor`,
`s`.`ignored` AS `ignored_site`,
`pc`.`id` AS `pc_id`,
`pc`.`name` AS `pc_name`,
`psc`.`id` AS `psc_id`,
`psc`.`name` AS `psc_name`,
`p`.`volume` AS `volume`,
MIN(`pos`.`position`) AS `position`,
`pos`.`id` AS `pos_id`
FROM `client` c
JOIN client_site cs ON cs.client_id = c.id
JOIN site s ON s.id = cs.site_id
JOIN site_phrase sp ON sp.site_id = s.id
JOIN phrase p ON p.id = sp.phrase_id
JOIN `position` pos ON pos.phrase_id = sp.phrase_id
AND pos.site_id = sp.site_id
LEFT JOIN `phrase_sub_category` `psc`
ON `psc`.`id` = `p`.`phrase_sub_category_id`
LEFT JOIN `phrase_category` `pc`
ON `pc`.`id` = `psc`.`phrase_category_id`
GROUP BY `p`.`id`,`s`.`id`,`serp`.`id`
ORDER BY `p`.`id`,`pos`.`position`
And here is a screenshot of the output the above query gets when I EXPLAIN / DESCRIBE it
http://img827.imageshack.us/img827/3336/indexsql.png
No matter how I alter the order of the tables above and how they are joined, the 1st or 2nd table always seems to be doing some sort of table scan. In the example of the screenshot, the problem table is sp. These tables are innoDB type, and there is appropriate indexes and foreign keys on all the tables I JOIN on. Any insights would be helpful.
MySQL will use a full table scan if it determines that it is faster than a using index. In the case of your SP table - with only 1300 records the table scan may be just as fast as a index.