Update with Subquery - sql

i have a Problem with a query.
I have a huge Table with Zipcodes from Germany called 'Postleitzahlen'.
There is another table with Companies called 'Firmen'
Structure is like this:
Firmen
------
ID
City
State
ZipCode
Postleitzahlen
--------------
ZipCode
State
Now I want, all empty ( '' or NULL ) State-fields of Firmen updated with their correspendants of Postleitzahlen
That's my actual query:
UPDATE
Firmen
SET
Firmen.State = Postleitzahlen.State
FROM
Postleitzahlen
INNER JOIN
Firmen ON Postleitzahlen.ZipCode = Firmen.ZipCode
WHERE
(
Firmen.State = ''
OR Firmen.State IS NULL )
I get a response with xx affected rows, but in fact, there's nothing updated.
Can someone help me?
Thanks in advance.
dennis

That looks like it should work correctly. What I would do is run the below query:
SELECT Firmen.State,Postleitzahlen.State
FROM
Postleitzahlen
INNER JOIN
Firmen ON Postleitzahlen.ZipCode = Firmen.ZipCode
WHERE
(
Firmen.State = ''
OR Firmen.State IS NULL )
See what that gets you. If your get results with values in both columns then you probably have a different issue. However, I am guessing that one of the columns is null or empty since you are updating rows but nothing is changed.
Then there has to be nothing wrong with your query. I think it might be with your update then. Try making the table an alias, like this:
UPDATE
F
SET
F.State = Postleitzahlen.State
FROM
Postleitzahlen
INNER JOIN
Firmen F ON Postleitzahlen.ZipCode = F.ZipCode
WHERE
(
F.State = ''
OR F.State IS NULL )

UPDATE
Firmen f
SET
f.State = (SELECT p.State FROM Postleitzahlen p WHERE p.ZipCode = f.ZipCode)
WHERE
(
f.State = ''
OR f.State IS NULL )

Related

SQL Update a Column From a Select

I want to update 1 column (loadStatus) in the Loads table based on if another column (IBLoad) from a joined table is NULL. The end result when running my statement has 0 rows affected. I'm not sure what's wrong here but maybe my WHERE clause is incorrect?
This is the first time I've tried to update from a select so trying to figure it out :)
UPDATE Loads SET loadStatus = 'SCHEDULED'
FROM (
Select L.OID as [LoadID], T.IBLoad, L.loadStatus
From [Loads] L left join [Transaction] T on L.OID = T.IBLoad
Where T.IBLoad is null and load_type = 1 ) i
WHERE Loads.loadStatus = null
you do not need subquery, And use is null instead of = null
UPDATE L
SET loadStatus = 'SCHEDULED'
From [Loads] L left join [Transaction] T on L.OID = T.IBLoad
Where T.IBLoad is null and load_type = 1
and L.loadStatus is null
or use Loads.loadStatus = '' for empty string
You don't need to update from a select in this case. Here is another way to write the query:
UPDATE l
SET loadStatus = 'SCHEDULED'
FROM Loads l
WHERE l.loadStatus IS NULL AND
l.load_type = 1 AND
NOT EXISTS (SELECT 1 FROM [Transaction] t WHERE l.OID = t.IBLoad);

Using IsNull() in a WHERE clause

This query:
SELECT
sc.ContactID
, c.Price
, p.ParkID
FROM
tblc c
JOIN tblsc ON c.ID= sc.ID
LEFT JOIN tblp p ON sc.ID= p.ID
WHERE
(stuff = stuff)
AND (stuff = stuff)
Returns this:
ContactID LeadSalePrice ParkID
-------------------------------------
1 50 NULL
2 60 22
Now, I am trying to set up another AND clause for ParkID. But, I only want to execute this AND on rows where ParkID IS NOT NULL. So, if on rows where ParkID IS NULL, we want to always keep those rows. On rows where ParkID IS NOT NULL, we only want to keep those rows if ParkID matches the parameter.
If #ParkID = 22, then return both rows.
If #ParkID <> 22, then only return the top row.
If #ParkID = NULL, then return both rows.
I've tried this:
SELECT
sc.ContactID
, c.Price
, p.ParkID
FROM
tblc c
JOIN tblsc ON c.ID= sc.ID
LEFT JOIN tblp p ON sc.ID= p.ID
WHERE
(stuff = stuff)
AND (stuff = stuff)
AND p.ParkID =
CASE WHEN p.ParkID IS NULL THEN
NULL
ELSE
#ParkID
END
This doesn't work because the proper way to compare with null is not:
= NULL
It's
IS NULL
For the same reason (I assume), this doesn't work either:
AND p.ParkID = Isnull(p.ParkID, #ParkID)
How do I do this?
Simply check if p.ParkID is NULL or it matches #ParkID:
WHERE p.ParkID IS NULL
OR p.ParkID = #ParkID
More compact:
WHERE p.ParkID IN ('', NULL)

is there a way to update a column using multiple tables

I'm trying to update a column called Specialty in a table called #LIST. I need to pull information from 3 different tables incase the specialty in 1 table is NULL. I prefer to use the specialty from the #Segment table, if that's NULL then I want to use the specialty from the #SUBMARKET table, and if that's NULL I want to use the specialty from the #MARKET table.
When I run the below query, it doesn't update any rows. I don't want to use more than 1 Update statement. What can I do?
UPDATE #LIST
SET Specialty = CASE WHEN (l.Segment__c is not NULL) THEN s.Specialty
WHEN (l.Segment__c is NULL) THEN b.Specialty
WHEN (l.Submarket__c is NULL) THEN m.Specialty
ELSE s.Specialty
END
FROM #LIST l
join #MARKET m on m.Market = l.Market__c
join #SUBMARKET b on b.Submarket = l.Submarket__c
join #Segment s on s.Segment = l.Segment__c
You need to use the table alias in the UPDATE. Also, I think you need left join:
UPDATE l
SET Specialty = CASE WHEN (l.Segment__c is not NULL) THEN s.Specialty
WHEN (l.Segment__c is NULL) THEN b.Specialty
WHEN (l.Submarket__c is NULL) THEN m.Specialty
ELSE s.Specialty
END
FROM #LIST l
left join #MARKET m on m.Market = l.Market__c
left join #SUBMARKET b on b.Submarket = l.Submarket__c
left #Segment s on s.Segment = l.Segment__c;
Otherwise, the NULL values will filter out rows, because they do not match in the join.

Slowness in update query using inner join

I am using the below query to update one column based on the conditions it is specified. I am using "inner join" but it is taking more than 15 seconds to run the query even if it has to update no records(0 records).
UPDATE CONFIGURATION_LIST
SET DUPLICATE_SERIAL_NUM = 0
FROM CONFIGURATION_LIST
INNER JOIN (SELECT DISTINCT APPLIED_MAT_CODE, APPLIED_SERIAL_NUMBER, COUNT(*) AS NB
FROM CONFIGURATION_LIST
WHERE
PLANT = '0067'
AND APPLIED_SERIAL_NUMBER IS NOT NULL
AND APPLIED_SERIAL_NUMBER !=''
AND DUPLICATE_SERIAL_NUM = 1
GROUP BY
APPLIED_MAT_CODE, APPLIED_SERIAL_NUMBER
HAVING
COUNT(*) = 1) T2 ON T2.APPLIED_SERIAL_NUMBER = CONFIGURATION_LIST.APPLIED_SERIAL_NUMBER
AND T2.APPLIED_MAT_CODE = CONFIGURATION_LIST.APPLIED_MAT_CODE
WHERE
CONFIGURATION_LIST.PLANT = '0067'
AND DUPLICATE_SERIAL_NUM = 1
The index is there with APPLIED_SERIAL_NUMBER and APPLIED_MAT_CODE and fragmentation is also fine.
Could you please help me on the above query performance.
First, you don't need the DISTINCT when using GROUP BY. SQL Server probably ignores it, but it is a bad idea anyway:
UPDATE CONFIGURATION_LIST
SET DUPLICATE_SERIAL_NUM = 0
FROM CONFIGURATION_LIST INNER JOIN
(SELECT APPLIED_MAT_CODE, APPLIED_SERIAL_NUMBER, COUNT(*) AS NB
FROM CONFIGURATION_LIST cl
WHERE cl.PLANT = '0067' AND
cl.APPLIED_SERIAL_NUMBER IS NOT NULL AND
cl.APPLIED_SERIAL_NUMBER <> ''
cl.DUPLICATE_SERIAL_NUM = 1
GROUP BY cl.APPLIED_MAT_CODE, cl.APPLIED_SERIAL_NUMBER
HAVING COUNT(*) = 1
) T2
ON T2.APPLIED_SERIAL_NUMBER = CONFIGURATION_LIST.APPLIED_SERIAL_NUMBER AND
T2.APPLIED_MAT_CODE = CONFIGURATION_LIST.APPLIED_MAT_CODE
WHERE CONFIGURATION_LIST.PLANT = '0067' AND
DUPLICATE_SERIAL_NUM = 1;
For this query, you want the following index: CONFIGURATION_LIST(PLANT, DUPLICATE_SERIAL_NUM, APPLIED_SERIAL_NUMBER, APPLIED_MAT_CODE, APPLIED_SERIAL_NUMBER).
The HAVING COUNT(*) = 1 suggests that you might really want NOT EXISTS (which would normally be faster). But you don't really explain what the query is supposed to be doing, you only say that this code is slow.
Looks like you're checking the table for rows that exist in the same table with the same values, and if not, update the duplicate column to zero. If your table has a unique key (identity field or composite key), you could do something like this:
UPDATE C
SET C.DUPLICATE_SERIAL_NUM = 0
FROM
CONFIGURATION_LIST C
where
not exists (
select
1
FROM
CONFIGURATION_LIST C2
where
C2.APPLIED_SERIAL_NUMBER = C.APPLIED_SERIAL_NUMBER and
C2.APPLIED_MAT_CODE = C.APPLIED_MAT_CODE and
C2.UNIQUE_KEY_HERE != C.UNIQUE_KEY_HERE
) and
C.PLANT = '0067' and
C.DUPLICATE_SERIAL_NUM = 1
I will try with a select first:
select APPLIED_MAT_CODE, APPLIED_SERIAL_NUMBER, count(*) as n
from CONFIGURATION_LIST cl
where
cl.PLANT='0067' and
cl.APPLIED_SERIAL_NUMBER IS NOT NULL and
cl.APPLIED_SERIAL_NUMBER <> ''
group by APPLIED_MAT_CODE, APPLIED_SERIAL_NUMBER;
How many rows do you get with this and how long does it take?
If you remove your DUPLICATE_SERIAL_NUM column from your table it might be very simple. The DUPLICATE_SERIAL_NUM suggests that you are searching for duplicates. As you count your rows you could introduce a simple table that contains the counts:
create table CLCOUNT ( N int unsigned, C int /* or what APPLIED_MAT_CODE is */, S int /* or what APPLIED_SERIAL_NUMBER is */, PLANT char(20) /* or what PLANT is */, index unique (C,S,PLANT), index(PLANT,N));
insert into CLCOUNT select count(*), cl.APPLIED_MAT_CODE, cl.APPLIED_SERIAL_NUMBER, cl.PLANT
from CONFIGURATION_LIST cl
where
cl.PLANT='0067' and
cl.APPLIED_SERIAL_NUMBER IS NOT NULL and
cl.APPLIED_SERIAL_NUMBER <> ''
group by APPLIED_MAT_CODE, APPLIED_SERIAL_NUMBER;
How long does this take?
Now you can simply select * from CLCOUNT where PLANT='0067' and N=1;
This is all far from being perfect. But you should be able to analyze (EXPLAIN SELECT ...) your queries and find why it takes so long.

need to replace subquery with JOIN

I need to use join in below instead of Subquery.
can anybody help me to rewrite this with JOIN.
update Table1
set status = 'Edited'
where val_74 ='1' and status ='Valid'
and val_35 is not null
and (val_35,network_id) in
(select val_35,network_id from
Table2 where val_35 is not null
and status='Correct_1');
update Table1 b SET (Val_12,Val_13,Val_14)=
(select Val_12,Val_13,Val_14 from
(select Val_35,network_id, Val_12, Val_13, Val_14
from Table2
where Val_34 is not null
and (REGEXP_LIKE(Val_13,'^[0-9]+$'))
and (Val_14 is null or (REGEXP_LIKE(Val_14,'^[0-9]+$')))
group by Val_35,network_id,Val_12,Val_13,Val_14
)
where Val_35 = b.Val_35 and network_id = b.network_id and rownum=1
)
where status = 'PCStep2' and (regexp_like(Val_13,'[MSS]+') or regexp_like(Val_14,'[MSS]+'));
I tried a lot with my less Knowledge In SQL JOINs. but getting multiple erros.
can anybody help me with the queries at the earliest.
Hearty thanks in advance
Actually you can not mix a update statement with a join statement. An update statement always expects exactly one table definition after the update command.
-- ORA-00971: missing SET keyword
update orders o, customers c
set o.order_value = c.account_value
where o.cust_id = c.cust_id
-- works fine
update orders o
set o.order_value = (select c.account_value
from customers c
where c.id = o.cust_id)