Case when to update multiple columns at once - tsql

I have never used Case before and am not sure how to do this but we have had some issues doing a wholesale update because of addresses changing that are now coming in the data that did not used to. I am trying to use it as an if then statement but I am sure that I am doing wrong. I need to update addresses when a field is either empty or null.
UPDATE defendants_ALL_Fixed
SET tiffAdd = tiffAdds.Add1, tiffZip = tiffAdds.Zip, tiffCity = tiffAdds.City, tiffState = tiffAdds.State
FROM defendants_ALL_Fixed INNER JOIN
tiffAdds ON defendants_ALL_Fixed.tiff = tiffAdds.Tiff
WHERE (defendants_ALL_Fixed.tiff = tiffAdds.Tiff)
I have tried wrapping that into a case statement such as:
SELECT
a.tiffAdd
, CASE WHEN a.tiffAdd = '' THEN
UPDATE defendants_ALL_Fixed
SET tiffAdd = tiffAdds.Add1, tiffZip = tiffAdds.Zip, tiffCity = tiffAdds.City, tiffState = tiffAdds.State
FROM defendants_ALL_Fixed INNER JOIN
tiffAdds ON defendants_ALL_Fixed.tiff = tiffAdds.Tiff
WHERE (defendants_ALL_Fixed.tiff = tiffAdds.Tiff)
END
FROM defendants_ALL_Fixed a
Which did not work and I understand why it does not work but have no idea where to go from here and any help would be great. We only use this once a month to update data (about 1.5 million records) and the resources it uses is not at all relevant at this point.
Thanks.

Assuming i am understanding your question (i.e. only update defendants_ALL_Fixed fields with tiffAdds when the defendants_ALL_Fixed fields are blank), you could do this as follows (sticking with case):
UPDATE defendants_ALL_Fixed
SET tiffAdd = CASE WHEN LTRIM(RTRIM(ISNULL(tiffAdd, ''))) = '' THEN tiffAdds.Add1
ELSE tiffAdd
END ,
tiffZip = CASE WHEN LTRIM(RTRIM(ISNULL(tiffZip, ''))) = '' THEN tiffAdds.Zip
ELSE tiffZip
END ,
tiffCity = CASE WHEN LTRIM(RTRIM(ISNULL(tiffCity, ''))) = '' THEN tiffAdds.City
ELSE tiffCity
END ,
tiffState = CASE WHEN LTRIM(RTRIM(ISNULL(tiffState, ''))) = '' THEN tiffAdds.State
ELSE tiffState
END
FROM defendants_ALL_Fixed
INNER JOIN tiffAdds ON defendants_ALL_Fixed.tiff = tiffAdds.Tiff
A simpler (or rather, easier to read) option is to do simple update statements based on a WHERE clause (one update statement per column):
UPDATE defendants_ALL_Fixed
SET tiffAdd = tiffAdds.Add1
FROM defendants_ALL_Fixed
INNER JOIN tiffAdds ON defendants_ALL_Fixed.tiff = tiffAdds.Tiff
WHERE ( LTRIM(RTRIM(ISNULL(tiffAdd, ''))) = '' )
Edit 1: based on your comment, That would suggest you can just update all columns where tiffAdd = ''? i.e.
UPDATE defendants_ALL_Fixed
SET tiffAdd = tiffAdds.Add1 ,
tiffZip = tiffAdds.Zip ,
tiffCity = tiffAdds.City ,
tiffState = tiffAdds.State
FROM defendants_ALL_Fixed
INNER JOIN tiffAdds ON defendants_ALL_Fixed.tiff = tiffAdds.Tiff
WHERE LTRIM(RTRIM(ISNULL(tiffAdd, ''))) = ''

Why dont you use merge instead? Use merge on every each field, checking if the value is not null or empty. I think it wpould be the best (used it on my own solution).

Related

How to decrease Query Time - Postgresql

PostgreSQL 9.6.9, compiled by Visual C++ build 1800, 64-bit
I have a question about query time. This 'view' has +1M data and when you execute select*from view , its query time is +400 seconds. On my query, it returns 10k data and query time is around 8-10 seconds. I am looking for a way to decrease it to 1 or 2 seconds. I tried changing or deleting things in my where or select clause, but only solution i came up with is limiting between "time" part.
If anyone know a better solution, that would be appreciated!
Thanks,
Can
Note: This view contains three different tables(cl_segments,cl_participants,cl_party_info).
I could not find a definition for those tables but i will add pictures of indexes and fields. Please let me know if you need any additional information.
clparticipantfields
clparticipantindexes
clpartyinfofields
clpartyinfoindexes
clsegmentsfields
clsegmentsindexes
EXPLAIN ANALYZE BUFFERS
select distinct on (clsgview.call_id)clsgview.call_id as call_id,
case when clsgview.src_dn_type = '0' and clsgview.dst_dn_type = '0' then
right(clsgview.src_dn,11)
when clsgview.src_dn_type = '1' and clsgview.dst_dn_type = '0' then
right(clsgview.src_caller_number,11)
when clsgview.src_dn_type = '0' and clsgview.dst_dn_type = ANY (ARRAY[1,12,13]) then
right(clsgview.src_dn,11) end as from,
case when clsgview.src_dn_type = '0' and clsgview.dst_dn_type = '0' then
right(clsgview.dst_dn,11)
when clsgview.src_dn_type = '1' and clsgview.dst_dn_type = '0' then
right(clsgview.dst_dn,11)
when clsgview.src_dn_type = '0' and clsgview.dst_dn_type = ANY (ARRAY[1,12,13]) then
right(clsgview.dst_display_name,11) end as to,
case when clsgview.act = ANY (ARRAY[5,6]) and clsgview.dst_dn_type != ANY (ARRAY[12]) then (end_time-start_time) else '00:00:00' end as talktime
from
( SELECT s.call_id,
s.id AS seg_id,
s.type AS seg_type,
s.seq_order AS seg_order,
s.start_time,
s.end_time,
si.dn_type AS src_dn_type,
si.dn AS src_dn,
si.display_name AS src_display_name,
si.firstlastname AS src_firstlastname,
si.caller_number AS src_caller_number,
dp.start_time AS dst_start_time,
dp.answer_time AS dst_answer_time,
dp.end_time AS dst_end_time,
dp.billing_rate AS dst_billing_rate,
di.dn_type AS dst_dn_type,
di.dn AS dst_dn,
di.display_name AS dst_display_name,
di.firstlastname AS dst_firstlastname,
di.caller_number AS dst_caller_number,
di.dn_class AS dst_dn_class,
s.action_id AS act,
ai.dn_type AS act_dn_type,
ai.dn AS act_dn,
ai.display_name AS act_display_name,
ai.firstlastname AS act_firstlastname
FROM ((((((cl_segments s
JOIN cl_participants sp ON ((sp.id = s.src_part_id)))
JOIN cl_participants dp ON ((dp.id = s.dst_part_id)))
JOIN cl_party_info si ON ((si.id = sp.info_id)))
JOIN cl_party_info di ON ((di.id = dp.info_id)))
LEFT JOIN cl_participants ap ON ((ap.id = s.action_party_id)))
LEFT JOIN cl_party_info ai ON ((ai.id = ap.info_id)))
order by seg_id desc
) as clsgview
where clsgview.src_dn_type = ANY (ARRAY[0,1])
and clsgview.dst_dn_type = ANY (ARRAY[0,1,12,13])
and clsgview.act != ANY (ARRAY[1]) and ((clsgview.act = ANY (ARRAY[15,101,102,103,107,400,409,418,419,421,423])) or (clsgview.act = ANY (ARRAY[5,6]) and clsgview.dst_dn_type = ANY (ARRAY[12])))
and clsgview.dst_display_name not like '*%' and clsgview.dst_caller_number not like '*%'
and (clsgview.src_dn = '1004' or clsgview.dst_dn = '1004')
and start_time::date BETWEEN '2020-01-01'::DATE and now()::DATE
order by clsgview.call_id desc

Case When isnt returning data for the null

I have a case statement that is not returning a null value. What am I missing in to get this to work.
Select CASE
WHEN transfer_sources.input_lot_type = 'Dried' THEN Sum(transfer_sources.weight)
WHEN transfer_sources.input_lot_type = 'Fresh' THEN NULL
END
from transfer_sources join bulk_lots on transfer_sources.source_id = bulk_lots.id
where transfer_sources.input_lot_type = 'Dried' and bulk_lots.name = 'BS190208-010'
group by transfer_sources.input_lot_type
LIMIT 1
I would like a null to show in the fresh column as i am trying to only calculate for dried
You need to remove WHERE condition transfer_sources.input_lot_type = 'Dried':
Select CASE
WHEN transfer_sources.input_lot_type = 'Dried' THEN Sum(transfer_sources.weight)
WHEN transfer_sources.input_lot_type = 'Fresh' THEN NULL
END
from transfer_sources join bulk_lots on transfer_sources.source_id = bulk_lots.id
where bulk_lots.name = 'BS190208-010'
group by transfer_sources.input_lot_type

How to select from subquery if column contains a specific value in postgre

I would like to ask if it is possible to select again from a result set if a column contains a specific value?
For example, from the below query I want to select it as subquery and check if that subquery's first column contains both 2 and 3 result. Otherwise, no values should be return.
select e.evaluator_id, ROUND(avg(cast(e.rating_score as int))::numeric,1)::varchar, c.q_category_name
from tms.t_evaluation e
inner join tms.m_q_category c
on e.nendo=c.nendo
and e.q_category_id = c.q_category_id
and c.delete_flg = '0'
inner join tms.m_q_subcategory qs
on e.q_category_id = qs.q_category_id
and e.q_subcategory_id = qs.q_subcategory_id
and c.nendo = qs.nendo
and qs.delete_flg = '0'
where e.nendo = '2018'
and e.empl_id = 'empl05'
and e.delete_flg = '0'
and e.evaluator_id in ('2' , '3')
group by e.empl_id, e.nendo, e.q_category_id,
c.q_category_name, e.evaluator_id, e.history_no
Result contains both 2 and 3 in first column. Is this possible?
select e.evaluator_id, ROUND(avg(cast(e.rating_score as int))::numeric,1)::varchar, c.q_category_name
from tms.t_evaluation e
inner join tms.m_q_category c
on e.nendo=c.nendo
and e.q_category_id = c.q_category_id
and c.delete_flg = '0'
inner join tms.m_q_subcategory qs
on e.q_category_id = qs.q_category_id
and e.q_subcategory_id = qs.q_subcategory_id
and c.nendo = qs.nendo
and qs.delete_flg = '0'
where e.nendo = '2018'
and e.empl_id = 'empl05'
and e.delete_flg = '0'
and e.evaluator_id in (select case when evaluator_id=2 or evaluator_id=3 then evaluator_id else null from t_evaluation order by evaluator_id asc)
group by e.empl_id, e.nendo, e.q_category_id,
c.q_category_name, e.evaluator_id, e.history_no

Variable "Rs.Temp" not found

I'm getting error while executing a sql query in Alpha Anywhere Query (AlphaADO) section.
The code i'm executing is attached.
SELECT * FROM
(SELECT
tbl_wo_kitting.wo_kitting_id,
tbl_wo_kitting.level_no,
tbl_wo_kitting.line_no_parent,
tbl_wo_kitting.line_no AS kitting_line_no,
tbl_wo_kitting.production_type,
tbl_wo_kitting.quantity AS kitting_quantity,
tbl_wo_kitting.release_to_wr,
tbl_wo_kitting.mpn,
m_product.m_product_id,
m_product.value,
m_product.name,
m_product.storelocator,
tbl_wo_project.wo_project_id,
tbl_wo_project.line_no AS project_line_no,
tbl_wo_project.quantity AS project_quantity,
m_transaction_moveqty_v.qtyonhand AS qtyonhand,
tbl_work_order.work_order_id,
tbl_work_order.reference_key,
case
when tbl_wo_kitting.level_no, = 'P+'
then '0'
else tbl_wo_kitting.level_no,
end as linenumber,
case
when tbl_wo_kitting.line_no_parent = 'PT+'
then '0'
else tbl_wo_kitting.line_no_parent
end as linenoparent
FROM (tbl_wo_kitting tbl_wo_kitting
INNER JOIN (m_product m_product
INNER JOIN m_transaction_moveqty_v m_transaction_moveqty_v
ON m_product.m_product_id = m_transaction_moveqty_v.m_product_id )
ON tbl_wo_kitting.m_product_id = m_product.m_product_id
INNER JOIN (tbl_wo_project tbl_wo_project
INNER JOIN tbl_work_order tbl_work_order
ON tbl_wo_project.work_order_id = tbl_work_order.work_order_id )
ON tbl_wo_kitting.wo_project_id = tbl_wo_project.wo_project_id )) AS TABLE1
ORDER BY tbl_wo_kitting.level_no, (string_to_array(linenoparent, '.'))::int[],(string_to_array(linenumber, '.'))::int[]
Any idea? This is selecting from PostgreSQL.
Thank you very much in advance.

tsql : Access query to TSQL union update conversion correct?

I have a query in access which i need to convert to a stored proc in sql server 2005.
the query in access is as follows:
UPDATE
tblitem,
tblFileSignature
SET
tblitem.strFileProcesstype = [tblFileSignature].[STRFILEPROCESSTYPE], tblitem.strFileSignatureType = [tblFileSignature].[strfilesignaturetype]
WHERE
(((tblitem.strFileSignatureType) Is Null) AND
((tblitem.strFileExclude)="n") AND
((InStr([tblitem].[strfilesignature],[tblFileSignature].[strsignature]))=1) AND ((tblitem.uidItemType)=1 Or (tblitem.uidItemType)=5) AND
((tblitem.uidCollection)=[forms]![frmSetup]![txtInputCol]) AND ((tblitem.strFileSignature) Not Like "d0c*") AND
((tblFileSignature.strFileProcessType) Not Like "ZIP"));
in tsql.. would this be the same?
update tblItem
set
i.strFileProcesstype = f.strFileProcesstype,
i.strFileSignatureType = f.strfilesignaturetype
from tblItem as I UNION tblFileSignature as F
WHERE (((i.strFileSignatureType) Is Null) AND
((i.strFileExclude)="n") AND
((i.[strfilesignature] like F.strsignature)) AND
((i.uidItemType)=1 Or
(i.uidItemType)=5) AND
((i.uidCollection)=#inputcolumn AND
((i.strFileSignature) Not Like 'd0c%') AND
((F.strFileProcessType) Not Like 'ZIP'));
thanks in advance
UPDATE:
so i'm going with the following. if i uncomment the declare and select clause and just execute from the declare down, it runs, if i comment the declare and select parts, it says error near ';'.
UPDATE I
SET
I.strFileProcesstype = F.STRFILEPROCESSTYPE,
I.strFileSignatureType = F.strfilesignaturetype
--declare #uidcollectionID int
--select I.strFileSignatureType
from
tblItem I
inner join tblFileSignature F
on
I.strfilesignature = left(F.strsignature,len(I.strfilesignature))
WHERE I.strFileSignatureType Is Null
AND I.strFileExclude='n'
AND I.uidItemType in (1,5)
AND I.uidCollection = #uidCollectionID
AND left(I.strFileSignature,3) <> 'd0c'
AND F.strFileProcessType <> 'ZIP';
any ideas?
You should change the
Double Quotes to Single Quotes
* to %
Replace the InStr with LIKE
Other than that, it looks fine to me.
No, you'd use a JOIN, not a UNION.
You can either make it a CROSS JOIN, and continue to apply the join conditions in the WHERE clause, or you can make it an inner join:
from tblItem as I INNER JOIN tblFileSignature as F
ON ((InStr(i.[strfilesignature],F.[strsignature]))=1)
And remove that condition from the WHERE clause (Lieven's answer also applies).
This should be close to what you need. May need to work on the join condition, but I think my conversion from INSTR will do it.
UPDATE i
SET strFileProcesstype = fs.STRFILEPROCESSTYPE,
strFileSignatureType = fs.strfilesignaturetype
FROM tblitem i
INNER JOIN tblFileSignature fs
ON i.strfilesignature = LEFT(fs.strsignature, LEN(i.strfilesignature))
WHERE i.strFileSignatureType IS Null
AND i.strFileExclude='n'
AND i.uidItemType IN (1,5)
AND i.uidCollection = #inputcolumn
AND LEFT(i.strFileSignature,3) <> 'd0c'
AND fs.strFileProcessType <> 'ZIP';