Update a range of rows in a table where the condition is in another table - sql

example:
table 1
invoice line article price
1 1 pen 10
1 2 mouse 11
1 3 paper 15
2 1 ... 25
2 2 ... 80
2 3 ...
2 4 ....
table 2
invoice date
1 2014-01-03 00:00:00.0000
2 2014-05-12 00:00:00.0000
3 2014-06-17 00:00:00.0000
how can I update the price only on the rows where the invoice date is for example the month of november
I know that i must use a join but i'm already joining this table for doing other stuff in the same query:
UPDATE invoicelines
SET invoicelines.netprice = ART.price
FROM invoicelines IL INNER JOIN items ITM
ON IL.item = ITM.item
i want to update the invoicelines with a specified date, but this date is in another table, and the situation is similar to the first example

update table1
set price = price + 10
from table1 t1 join table2 t2 on t1.invoice = t2.invoice
where month(t2.date) = 11

As to "I know that i must use a join": No, you don't have to join. When a condition is in another table you would usually use EXISTS or IN.
update table1
set price = ...
where invoice in
(
select invoice
from table2
where month(`date`) = 11
);
Or:
update table1
set price = ...
where exists
(
select *
from table2
where month(table2.`date`) = 11
and table2.invoice = table1.invoice
);
You forgot to name your dbms. Date functions are mostly dbms specific, so a MONTH function may be available or not.

I Solved With This
UPDATE Invoicelines
SET Invoicelines.NetPrice = ART.Price
FROM Invoicelines BR INNER JOIN Items ART join InvoiceHead bt on month(bt.docdate)=11
ON BR.Item = ART.Item
where BR.sheetNumber=bt.sheetNumber

Related

case when results as left join condition

Table 1
Staff category hours cost
1 Cleaning 5 20
1 Scrubbing 6 30
1 Cleaning 8 40
2 Scrubbing 4 30
table 2
`
Staff type vendor category
1 part A Cleaning
1 full b Cleaning
1 full c Scrubbing
...’
To join these two tables I added a new col “type”:
Case when table1.hours=8
Then ”full”
Else ”part”
End as “type”
From table1
Left join table2 on type=table2.type
And Table 1.staff =table2.staff
And Table1.category=table 2.category
My desired outcome is
Staff category Cost vendor type
1 Cleaning 20 A. Part
1 Cleaning 40 B. Full
1 Scrubbing 30 C. Part
However the type=table2.type condition didn’t work so it became
Staff category Cost vendor type
1 Cleaning 20 A. Part
1 Cleaning 20 B. part
1 cleaning 40. A Full
1. Cleaning 40 B. Full
Below is for BigQuery Standard SQL
#standardSQL
SELECT staff, category, cost, vendor, type
FROM (
SELECT *, IF(hours = 8, 'full', 'part') AS type
FROM `project.dataset.table1`
) t1
LEFT JOIN `project.dataset.table2` t2
USING (type, staff, category)
If I have not understood, you want an implementation that creates a column in table1 and then joins with table2 on the condition table1.category = table2.category and table1.type = table2.type. If that's the case you could try with the following:
SELECT t1.Staff, t1.category, t1.cost, table2.vendor, t1.type
FROM (
SELECT *, CASE WHEN table1.hours = 8 THEN "full" ELSE "part" END as type
FROM table1
) t1
INNER JOIN table2
ON t1.category = table2.category
AND t1.type = table2.type
AND t1.staff = table2.staff

SQL execution time

I face execution time problem here ,really upset
UPDATE [OT]
SET AAA = 8
WHERE ID in
(
select UID from [IP] B
inner join [OT] A
on B.ADDR = A.ADDR and A.ID=B.ID
)
AND AAA= 6 ;
OT table have duplicate ID, count(*) about 900000 rows
IP table have unique ID, count(*) about 800000 rows
AAA is a column of OT table type: tinyint
select count(*) from OT where AAA=6 about 150000
I do not know why this query will take more than 1 hour ??
My other similar query only take 10 seconds
I would just write this more simply as:
UPDATE OT
SET AAA = 8
FROM OT
WHERE EXISTS (SELECT 1 FROM IP WHERE IP.ADDR = OT.ADDR AND IP.ID = OT.ID) AND
OT.AAA = 6 ;
For performance, you want indexes on OT(AAA) and IP(ADDR, ID).

SQL Update Skipping duplicates

Table 1 looks like the following.
ID SIZE TYPE SERIAL
1 4 W-meter1 123456
2 5 W-meter2 123456
3 4 W-meter 585858
4 4 W-Meter 398574
As you can see. Items 1 and 2 both have the same Serial Number. I have an innerjoin update statement that will update the UniqueID on these devices based on linking their serial number to the list.
What I would like to do. Is modify by hand the items with duplicate serial numbers and scripted update the ones that are unique. Im presuming I have to reference the distinct command here somewhere buy not sure.
This is my update statement as is. Pretty simple and straight forward.
update UM00400
Set um00400.umEquipmentID = tb2.MIUNo
from UM00400 tb1
inner join AA_Meters tb2 on
tb1.umSerialNumber = tb2.Old_Serial_Num
where tb1.umSerialNumber <> tb2.New_Serial_Num
;WITH CTE
AS
(
SELECT * , rn = ROW_NUMBER() OVER (PARTITION BY SERIAL ORDER BY SERIAL)
FROM UM00400
)
UPDATE CTE
SET CTE.umEquipmentID = tb2.MIUNo
inner join AA_Meters tb2
on CTE.umSerialNumber = tb2.Old_Serial_Num
where tb1.umSerialNumber <> tb2.New_Serial_Num
AND CTE.rn = 1
This will update the 1st record of multiple records with the same SERIAL.
If i understand your question correctly below query will help you out :
;WITH CTE AS
(
// getting those serial numbers which are not duplicated
SELECT umSerialNumber,COUNT(umSerialNumber) as CountOfSerialNumber
FROM UM00400
GROUP BY umSerialNumber
HAVING COUNT(umSerialNumber) = 1
)
UPDATE A SET A.umEquipmentID = C.MIUNo
FROM UM00400 A
INNER JOIN CTE B ON A.umSerialNumber = B.umSerialNumber
INNER JOIN AA_Meters C ON A.umSerialNumber = C.Old_Serial_Num

SQL select column equivalence

I have a table that saves the possible states of other tables (entities).
But now I need to find equivalence of states between two entities.
The table structure is something like this
ID TableID StateValue StateDefinition StateDescription
================================================================
1 1 1 Created Just created
2 1 2 Dropped Just Dropped
3 2 1 Created Just Created
4 2 2 Aproved Passed the revision
5 2 3 Dropped Just dropped
I want to get equivalent (comparing text of state) which as a result get this:
TableID1 StateValue1 TableID2 StateValue2 StateDefinition
=============================================================================
1 1 2 1 Created
1 2 2 3 Dropped
My question is, how can it be done??
Do a self join on the table.
A general case might look like:
SELECT A.TableID as TableId1,
A.StateValue as StateValue1,
B.TableId as TableId2,
B.StateValue as StateValue2,
A.StateDefinition
FROM
Table A
INNER JOIN Table B
ON (A.TableId <> B.TableId and A.StateDefiniton = B.StateDefinition)
select t1.TableID as TableID1,
t1.StateValue as StateValue1,
t2.TableID as TableID2,
t2.StateValue as StateValue2,
t1.StateDefinition
from MyTable t1
inner join MyTable t2 on t1.TableID = 1 and t2.TableID = 2
where t1.StateValue = t2.StateValue
and t1.StateDefinition = t2.StateDefinition

Using (IN operator) OR condition in Where clause as AND condition

Please look at following image, I have explained my requirements in the image.
alt text http://img30.imageshack.us/img30/5668/shippment.png
I can't use here WHERE UsageTypeid IN(1,2,3,4) because this will behave as an OR condition and fetch all records.
I just want those records, of first table, which are attached with all 4 ShipmentToID .
All others which are attached with 3 or less ShipmentToIDs are not needed in result set.
Thanks.
if (EntityId, UsageTypeId) is unique:
select s.PrimaryKeyField, s.ShipmentId from shipment s, item a
where s.PrimaryKeyField = a.EntityId and a.UsageTypeId in (1,2,3,4)
group by s.PrimaryKeyField, s.ShipmentId having count(*) = 4
otherwise, 4-way join for the 4 fields,
select distinct s.* from shipment s, item a, item b, item c, item d where
s.PrimaryKeyField = a.EntityId = b.EntityId = c.EntityId = d.EntityId and
a.UsageTypeId = 1 and b.UsageTypeId = 2 and c.UsageTypeId = 3 and
d.UsageTypeId = 4
you'll want appropriate index on (EntityId, UsageTypeId) so it doesn't hang...
If there will never be duplicates of the UsageTypeId-EntityId combo in the 2nd table, so you'll never see:
EntityUsageTypeId | EntityId | UsageTypeId
22685 | 4477 | 1
22687 | 4477 | 1
You can count matching EntityIds in that table.
WHERE (count(*) in <tablename> WHERE EntityId = 4477) = 4
DECLARE #numShippingMethods int;
SELECT #numShippingMethods = COUNT(*)
FROM shippedToTable;
SELECT tbl1.shipmentID, COUNT(UsageTypeId) as Usages
FROM tbl2 JOIN tbl1 ON tbl2.EntityId = tbl1.EntityId
GROUP BY tbl1.EntityID
HAVING COUNT(UsageTypeId) = #numShippingMethods
This way is preferred to the multiple join against same table method, as you can simply modify the IN clause and the COUNT without needing to add or subtract more tables to the query when your list of IDs changes:
select EntityId, ShipmentId
from (
select EntityId
from (
select EntityId
from EntityUsage eu
where UsageTypeId in (1,2,3,4)
group by EntityId, UsageTypeId
) b
group by EntityId
having count(*) = 4
) a
inner join Shipment s on a.EntityId = s.EntityId