Save query result into specific column - sql

This might seem like a noob question, but here's the thing:
In the image, the first table name is facturaDetalle and the second one's facturamaster
I want to SUM all the total matching idfactura in facturadetalle and save them into the total column in the facturamaster table.
I'm working on a master-detail form in ASP.NET

UPDATE m
SET total = (SELECT SUM(d.total) FROM dbo.facturadetalle d WHERE d.idfactura = m.idfactura)
FROM dbo.facturamaster m
--WHERE m.total IS NULL

You can use UPDATE statement to do that.
UPDATE m
SET TOTAL = SUM(d.Total)
FROM idfactura AS m
INNER JOIN idfacturaldetelle AS d
ON m.idfactura = d.idfactura

Related

How does this update query set the sum when it has a joins

UPDATE
Chemicals.dbo.ChmProductCompositions
SET Vhap = SUM(PercentOfProduct)
FROM
Chemicals.dbo.ChmProductCompositions PC
JOIN Chemicals.dbo.ChmCompositionChemicals CC ON CC.ProductCompositionID = pc.ProductCompositionID
JOIN Chemicals.dbo.ChmChemicals C ON C.ChemicalID = CC.ChemicalID
WHERE IsHazardous = 1
I have the query above and I was wondering does something like the above query get the total sum and set it or the sum for each specific and set it?
I was also wondering if it gets the total sum and sets each one to the total how might I go about getting the sum for each individual item and then set it to that?
It doesn't. Just try the query -- it is totally safe, because it returns an error. UPDATEs are not aggregations, so SUM() is not allowed.
You need to aggregate before joining:
UPDATE pc
SET Vhap = cc.PercentOfProduct
FROM Chemicals.dbo.ChmProductCompositions pc JOIN
(SELECT cc.ProductCompositionID, SUM(PercentOfProduct) as PercentOfProcue
FROM Chemicals.dbo.ChmCompositionChemicals CC JOIN
Chemicals.dbo.ChmChemicals C
ON C.ChemicalID = CC.ChemicalID
GROUP BY cc.ProductCompositionID
) cc
ON CC.ProductCompositionID = pc.ProductCompositionID
WHERE IsHazardous = 1;
Note that IsHazardous may belong in the subquery. Your question is not clear.
You have two levels of the problem. First, you need to perform an aggregation. Next, you need to update the corresponding record for each record in the aggregates. You can perform this as Gordon Linoff described in a subquery, or, you can use temporary tables instead. Let's assume that you have a table
pc_temp(ProductCompositionID, result)
insert-select:
INSERT INTO pc_temp(ProductCompositionID, result)
SELECT PC.ProductCompositionID, SUM(PercentOfProduct)
FROM
Chemicals.dbo.ChmProductCompositions PC
JOIN Chemicals.dbo.ChmCompositionChemicals CC ON CC.ProductCompositionID = pc.ProductCompositionID
JOIN Chemicals.dbo.ChmChemicals C ON C.ChemicalID = CC.ChemicalID
WHERE IsHazardous = 1
So you end up with records in the temp table that can be used in your simplified update because the aggregation already happened.
simplified update:
UPDATE PC
SET Vhap = result
FROM
Chemicals.dbo.ChmProductCompositions PC
JOIN pc_temp
ON PC.ProductCompositionID = pc_tmp.ProductCompositionID;

MS Access SQL left join giving all 0

I am trying to make a summary table of all the items I have. I have a raw data table with 10 users who respectively have different items. There are maximum 3 different items and I want to do a count to see how many items each individual has. The following is my code.
Select b.Country,b.UserID,Num_including_fruits, Apple,Orange
from
(((SELECT o.Country,o.UserID, IIF(ISNULL(Count(o.UserID)),0,Count(o.UserID))
AS Num_including_fruits
FROM [SEA2_View] as o
GROUP BY o.UserID, o.Country
ORDER BY Country)as b
LEFT JOIN
(SELECT o.Country,o.UserID,IIF(ISNULL(Count(o.UserID)),0,Count(o.UserID)
AS Apple
FROM [APAC2_View] as o
WHERE o.fruit_status <>"fresh" AND o.HWType = "Apple"
GROUP BY o.Country,o.UserID)as d
ON (b.UserID = d.UserID))
LEFT JOIN
(SELECT o.Country,o.UserID,IIF(ISNULL(Count(o.UserID)),0,Count(o.UserID))
AS Orange
FROM [SEA2_View] as o
WHERE o.fruit_status <>"fresh" AND o.HWType = "Orange"
GROUP BY o.Country,o.UserID)as e
ON (d.UserID = e.UserID))
;
The first join returns the correct result but the second join somehow returns all 0, which is incorrect. Therefore please help! and I would appreciate any advice for best practice when it comes to joins in SQL. Thanks lot!
Are you sure you don't have a table naming error?
You're first joining [SEA2_View] with [APAC2_View]. The second join is joining with [SEA2_View] with itself.

SQL Update with Multiple updates per Record

I am trying to update months of a given persons records to reduce their potential if they get a claim within a month.
UPDATE M
SET POTENTIAL_HITS = POTENTIAL_HITS - 1
FROM #TEMP_CDC_MEMBERS M
INNER JOIN #TEMP_CDC_CLAIMS C ON M.CIN = C.CIN AND C.MEASURE_INDICATOR = M.SUB_MEASURE
WHERE M.MOE > C.MOE
The MOE is a month field in a 201607 format.
The problem I am having is if there is a hit in one month, that difference will be ignored in a later month (due to SQL transactions).
Is there a way to update the potential without using a loop?
Your problem is that update doesn't do cumulative updates -- only one update per record in m. I think you can do what you want using cross apply:
UPDATE M
SET POTENTIAL_HITS = POTENTIAL_HITS - c.cnt
FROM #TEMP_CDC_MEMBERS M CROSS APPLY
(SELECT COUNT(*) as cnt
FROM #TEMP_CDC_CLAIMS C
WHERE M.CIN = C.CIN AND C.MEASURE_INDICATOR = M.SUB_MEASURE AND M.MOE > C.MOE) c;

How can I do a SQL join to get a value 4 tables farther from the value provided?

My title is probably not very clear, so I made a little schema to explain what I'm trying to achieve. The xxxx_uid labels are foreign keys linking two tables.
Goal: Retrieve a column from the grids table by giving a proj_uid value.
I'm not very good with SQL joins and I don't know how to build a single query that will achieve that.
Actually, I'm doing 3 queries to perform the operation:
1) This gives me a res_uid to work with:
select res_uid from results where results.proj_uid = VALUE order by res_uid asc limit 1"
2) This gives me a rec_uid to work with:
select rec_uid from receptor_results
inner join results on results.res_uid = receptor_results.res_uid
where receptor_results.res_uid = res_uid_VALUE order by rec_uid asc limit 1
3) Get the grid column I want from the grids table:
select grid_name from grids
inner join receptors on receptors.grid_uid = grids.grid_uid
where receptors.rec_uid = rec_uid_VALUE;
Is it possible to perform a single SQL that will give me the same results the 3 I'm actually doing ?
You're not limited to one JOIN in a query:
select grids.grid_name
from grids
inner join receptors
on receptors.grid_uid = grids.grid_uid
inner join receptor_results
on receptor_results.rec_uid = receptors.rec_uid
inner join results
on results.res_uid = receptor_results.res_uid
where results.proj_uid = VALUE;
select g.grid_name
from results r
join resceptor_results rr on r.res_uid = rr.res_uid
join receptors rec on rec.rec_uid = rr.rec_uid
join grids g on g.grid_uid = rec.grid_uid
where r.proj_uid = VALUE
a small note about names, typically in sql the table is named for a single item not the group. thus "result" not "results" and "receptor" not "receptors" etc. As you work with sql this will make sense and names like you have will seem strange. Also, one less character to type!

Update 1 field in a table from another field in a different table (OS400, not a 1 to 1 relationship)

Im trying to update a field in a table from another field in a different table.
The table being updated will have multiple records that need updating from 1 match in the other table.
Example, i have a 1 million row sales history file. Those million records have aproximately 40,000 different sku codes, each row has a date and time stamp. Each sku will have multiple records in there.
I added a new field called MATCOST (material cost).
I have a second table containing SKU and the MATCOST.
So i want to stamp every line in table 1 with the corresponding SKU's MATCOST in table2. I cannot seem to achieve this when its not a 1 to 1 relationship.
This is what i have tried:
update
aulsprx3/cogtest2
set
matcost = (select Matcost from queryfiles/coskitscog where
aulsprx3/cogtest2.item99 = queryfiles/coskitscog.ITEM )
where
aulsprx3/cogtest2.item99=queryfiles/coskitscog.ITEM
But that results in the SQL error: Column qualifier or table COSKITSCOG undefined and highlighting the q in the last reference to queryfiles/coskitscog.Item
Any idea's ?
Kindest Regards
Adam
Update: This is what my tables look like in principle. 1 Table contains the sales data, the other contains the MATCOSTS for the items that were sold. I need to update the Sales Data table (COGTEST2) with the data from the COSKITCOG table. I cannot use a coalesce statement because its not a 1 to 1 relationship, most select functions i use result in the error of multiple selects. The only matching field is Item=Item99
I cant find a way of matching multiple's. In the example we would have to use 3 SQL statements and just specify the item code. But in live i have about 40,000 item codes and over a million sales data records to update. If SQL wont do it, i suppose i'd have to try write it in an RPG program but thats way beyond me for the moment.
Thanks for any help you can provide.
Ok this is the final SQL statement that worked. (there were actually 3 values to update)
UPDATE atst2f2/SAP20 ct
SET VAL520 = (SELECT cs.MATCOST
FROM queryfiles/coskitscog cs
WHERE cs.ITEM = ct.pnum20),
VAL620 = (SELECT cs.LABCOST
FROM queryfiles/coskitscog cs
WHERE cs.ITEM = ct.pnum20),
VAL720 = (SELECT cs.OVRCOST
FROM queryfiles/coskitscog cs
WHERE cs.ITEM = ct.pnum20),
WHERE ct.pnum20 IN (SELECT cs.ITEM
FROM queryfiles/coskitscog cs)
This more compact way to do the same thing should be more efficient, eh?
UPDATE atst2f2/SAP20 ct
SET (VAL520, VAL620, VAL720) =
(SELECT cs.MATCOST, cs.LABCOST, cs.OVRCOST
FROM queryfiles/coskitscog cs
WHERE cs.ITEM = ct.pnum20)
WHERE ct.pnum20 IN (SELECT cs.ITEM
FROM queryfiles/coskitscog cs)
Qualify the columns with correlation names.
UPDATE AULSPRX3/COGTEST2 A
SET A.matcost = (SELECT matcost
FROM QUERYFILES/COSKITSCOG B
WHERE A.item99 = B.item)
WHERE EXISTS(SELECT *
FROM QUERYFILES/COSKITSCOG C
WHERE A.item99 = C.item)
From UPDATE, I'd suggest:
update
aulsprx3/cogtest2
set
(matcost) = (select Matcost from queryfiles/coskitscog where
aulsprx3/cogtest2.item99 = queryfiles/coskitscog.ITEM)
where
aulsprx3/cogtest2.item99=queryfiles/coskitscog.ITEM
Note the braces around matcost.