How do I update a column on a table where duplicate records are found - sql

I have this sql script that selects duplicate record . i want to convert it to an update statement where it updates are particular column called STATUS in the table with the string "Duplicated"
Dbms is Oracle
Select * From (
select * from VisaNnsMainTable
Where TRN_TYPE = '500' OR TRN_TYPE = '2500') A
inner join (
select ARN,WAN_NUM, ABS(TRN_AMOUNT) AS AMOUNT
from VisaNnsMainTable
Where TRN_TYPE = '500' OR TRN_TYPE = '2500'
group by ARN, WAN_NUM,ABS(TRN_AMOUNT)
having count(*) > 1
) B on A.ARN = B.ARN
and A.WAN_NUM = B.WAN_NUM
and ABS(A.TRN_AMOUNT) = B.AMOUNT
ORDER BY A.WAN_NUM
Please help me review this I think it does what I want ,but I am not sure if i wrote it well
UPDATE VisaNnsMainTable
SET EXCEPTION = 'Duplicate'
where CONCAT(ARN,WAN_NUM,ABS(TRN_AMOUNT)) in
( select CONCAT(ARN,WAN_NUM,ABS(TRN_AMOUNT))
from VisaNnsMainTable
group by CONCAT(ARN,WAN_NUM,ABS(TRN_AMOUNT))
having count(*) > 1 ) AND (TRN_TYPE = '500' OR TRN_TYPE = '2500')

Related

SQL nested grouping issue

Here's my query:
select
cast(ar.AudienceCreationDate as date) as AudienceDate,
Count(*) as [Count],
count(case when ar.Source = 'Contact' then ar.Id end) as PatientCount,
count(case when ar.Source = 'PatientContact' then ar.Id end) as PatientContactCount,
(
select
count(*)
from
_SMSMessageTracking sms
inner join
[CTT Preferences] pref on pref.ContactId = sms.SubscriberKey
where
sms.Name <> 'ky_ctt_join' and pref.Source = 'Patient'
) as PatientSMS,
(
select
count(*)
from
_SMSMessageTracking sms
inner join
[CTT Preferences] pref on pref.ContactId = sms.SubscriberKey
where
sms.Name <> 'ky_ctt_join' and pref.Source = 'PatientContact'
) as PatientContactSMS
from
Daily_Symptom_Check_Audience_Archive ar
group by
cast(ar.AudienceCreationDate as date)
And here's the result set it creates:
The issue I'm having is that the values in the rightmost two columns are the same across the board, for all records. This number represents the TOTAL, and not aggregated by day, as the other values indicate. I realize that I'm doing something wrong - what can I do to modify my query to effectively have a proper "grouping" on these last two columns just like all the other data in this table?
in the where clause of the nested query add sms.AudienceDate = ar.AudienceDate

Long Running Query - Recommendations to improve performance in Redshift

SELECT
A.load,
A.sender,
A.latlong,
COUNT(distinct B.load) as load_count,
COUNT(distinct B.sender) as sender_count
FROM TABLE_A A
JOIN TABLE_B B ON
A.sender <> B.sender AND
(
A.latlong = B.latlong
or
(
lower(A.address_line1) = lower(B.address_line1)
and lower(A.city) = lower(B.city)
and lower(A.state) = lower(B.state)
and lower(A.country) = lower(B.country)
)
)
GROUP BY A.load, A.sender, A.latlong ;
I am trying to run a query as above sample, which runs for more time (approx 2 hrs) which is not at all expected. I am trying to split the query and do UNION but the result sets are not matching.
Can you please help with options to improve this query performance or alternative ways to achieve this in AWS?
Approximately 1.5 million records
I would suggest removing the to lower function and sanitizing the data to be lower case
select
A.load, A.sender, A.latlong,
count(distinct B.load) as load_count,
count(distinct B.sender) as sender_count
from
TABLE_A A
join
TABLE_B B
on
A.sender <> B.sender and
(
A.latlong = B.latlong
or
(
A.address_line1 = B.address_line1
and A.city) = B.city)
and A.state) = B.state)
and A.country) = B.country)
))
group by
A.load, A.sender, A.latlong ;

Should a subquery on a join use tables from an outer query in the where clause?

I need to add a subquery to a join, because one payment can have more than one allotment, so I only need to account for the first match (where rownum = 1).
However, I'm not sure if adding pmt from the outer query to the subquery on the allotment join is best.
Should I be doing this differently in the event of performance hits, etc.. ?
SELECT
pmt.payment_uid,
alt.allotment_uid,
FROM
payment pmt
/* HERE: is the reference to pmt.pay_key and pmt.client_id
incorrect in the below subquery? */
INNER JOIN allotment alc ON alt.allotment_uid = (
SELECT
allotment_uid
FROM
allotment
WHERE
pay_key = pmt.pay_key
AND
pay_code = 'xyz'
AND
deleted = 'N'
AND
client_id = pmt.client_id
AND
ROWNUM = 1
)
WHERE
AND
pmt.deleted = 'N'
AND
pmt.date_paid >= TO_DATE('2017-07-01')
AND
pmt.date_paid < TO_DATE('2017-10-01') + 1;
It's difficult to identify the performance issue in your query without seeing an explain plan output. You query does seem to do an additional SELECT on the allotment for every record from the main query.
Here is a version which doesn't use correlated sub query. Obviously I haven't been able to test it. It does a simple join in and then filters all records except one of the allotments. Hope this helps.
WITH v_payment
AS
(
SELECT
pmt.payment_uid,
alt.allotment_uid,
ROW_NUMBER () OVER(PARTITION BY allotment_id) r_num
FROM
payment pmt JOIN allotment alt
ON (pmt.pay_key = alt.pay_key AND
pmt.client_id = alt.client_id)
WHERE pmt.deleted = 'N' AND
pmt.date_paid >= TO_DATE('2017-07-01') AND
pmt.date_paid < TO_DATE('2017-10-01') + 1 AND
alt.pay_code = 'xyz' AND
alt.deleted = 'N'
)
SELECT payment_uid,
allotment_uid
FROM v_payment
WHERE r_num = 1;
Let's know how this performs!
You can phrase the query that way. I would be more likely to do:
SELECT . . .
FROM payment p INNER JOIN
(SELECT a.*,
ROW_NUMBER() OVER (PARTITION BY pay_key, client_id
ORDER BY allotment_uid
) as seqnum
FROM allotment a
WHERE pay_code = 'xyz' AND deleted = 'N'
) a
ON a.pay_key = p.pay_key AND a.client_id = p.client_id AND
seqnum = 1
WHERE p.deleted = 'N' AND
p.date_paid >= DATE '2017-07-01' AND
p.date_paid < (DATE '2017-10-01') + 1;

update columns using select statement

I want to update columns based on result of select statement you find my query below ,my code doesn't work correctly :
I get the same data on all my columns
update ACHATS b set
QUANTITE=(select sum(QUANTITE) from ACHAT_DETAILS a where a.NUMERO_D_ACHAT=(SELECT max(ID_ACHAT) M_ID_ACHAT from ACHATS)
group by a.NUMERO_D_ACHAT) ,
PRIX_HT=(select sum(PRIX_HT) from ACHAT_DETAILS a where a.NUMERO_D_ACHAT=(SELECT max(ID_ACHAT) M_ID_ACHAT from ACHATS)
group by a.NUMERO_D_ACHAT),
PRIX_TTC=(select sum(PRIX_HT) from ACHAT_DETAILS a where a.NUMERO_D_ACHAT=(SELECT max(ID_ACHAT) M_ID_ACHAT from ACHATS)
group by a.NUMERO_D_ACHAT);
The correct update query for the question is:
update ACHATS b set
QUANTITE = (select sum(QUANTITE)
from ACHAT_DETAILS a
where a.NUMERO_D_ACHAT = (
select max(ID_ACHAT)
from ACHATS)
),
PRIX_HT = (select sum(PRIX_HT)
from ACHAT_DETAILS a
where a.NUMERO_D_ACHAT = (
select max(ID_ACHAT)
from ACHATS)
),
PRIX_TTC = (select sum(PRIX_HT)
from ACHAT_DETAILS a
where a.NUMERO_D_ACHAT = (
select max(ID_ACHAT)
from ACHATS)
)
where b.ID_ACHAT = (select max(ID_ACHAT)
from ACHATS)
So to test this out try the below code to see if that is the results you were expecting to use to update your table first:
WITH B AS (
SELECT MAX(M_ID_ACHAT) AS NUMERO_D_ACHAT
, SUM(QUANTITE) AS QUANTITE
, SUM(PRIX_HT) AS PRIX_HT
, SUM(PRIX_TTC) AS PRIX_TTC
FROM ACHAT_DETAILS
GROUP BY
MAX(M_ID_ACHAT)
)
SELECT
b.QUANTITE
,b.PRIX_HT
,b.PRIX_TTC
FROM ACHAT_DETAILS a
JOIN b
ON a.NUMERO_D_ACHAT = b.NUMERO_D_ACHAT
Next if that all looks good then you can run this (I think I got the syntax correct):
WITH A AS (
SELECT MAX(M_ID_ACHAT) AS NUMERO_D_ACHAT
, SUM(QUANTITE) AS QUANTITE
, SUM(PRIX_HT) AS PRIX_HT
, SUM(PRIX_TTC) AS PRIX_TTC
FROM ACHAT_DETAILS
GROUP BY
MAX(M_ID_ACHAT)
)
MERGE INTO ACHATS AS u
USING A
ON u.NUMERO_D_ACHAT = a.NUMERO_D_ACHAT
WHEN MATCHED THEN
UPDATE
SET
u.QUANTITE = a.QUANTITE
,u.PRIX_HT = a.PRIX_HT
,u.PRIX_TTC = a.PRIX_TTC

Merge Source Table Into Target Table using subjoins

I am new to SQLDeveloper. Please help me in correcting the merge syntax.I want to merge the data from act_sl tavle into act_sls_0 table
I am using 2 joins in From Clause.
But I am Getting Errors :
Error(13,13): PL/SQL: ORA-00969: missing ON keyword
Error(4,1): PL/SQL: SQL Statement ignored
merge into act_sls_0 using(
( select * from
(select a_0.asp, gadim.uic as ga, pmm_styleid, week, colorcode , sizecode, storenum, units_asly,retail_asly,
cost_asly ,units_asregly,retail_asregly,units_asmkdly,retail_asmkdly,units_as_pln,retail_as_pln
from act_sls
join dimension w on w.externalkey = 'W'||substr(WEEK,3,2)||'_'||substr(WEEK,5,2)
join a_0 on ( w.externalkey between startweek and endweek)
join dimension strdim on strdim.externalkey = (case when length(storenum) <= 4 then RPAD('STR-', 8 - length(storenum), '0') else 'STR-' END) || storenum
join store_info_0 str on store = strdim.uic
join dimension gadim on gadim.externalkey = decode(store_type, 'RETAIL', 'GA-01', 'ECOM', 'GA-02', '')
where trendweeks < 6)t1
join(select distinct asp, product, ga, color, sstyl_shade, pmm_styleid from aplc_1 aplc
join apc_1 apc using (asp,product,color)
where activeitem = 1 and ga!=0 and color != 0)t2
on (t1.asp = t2.asp and
t1.pmm_styleid = t2.pmm_styleid
and (case when length(t1.colorcode) <= 4 then RPAD('SHD-', 8 - length(t1.colorcode), '0') else 'SHD-' END) || t1.colorcode = t2.sstyl_shade
and t1.ga = t2.ga))src
on (trg.asp = src.asp and trg.pmm_styleid = src.pmm_styleid and trg.colorcode = src.colorcode and trg.ga = src.ga)
when matched THEN
update SET
when matched THEN
update SET
trg.UNITS_ASLY = src.UNITS_ASLY,
trg.RETAIL_ASLY = src.RETAIL_ASLY,
trg.COST_ASLY = src.COST_ASLY,
trg.UNITS_ASREGLY = src.UNITS_ASREGLY,
trg.RETAIL_ASREGLY = src.RETAIL_ASREGLY,
trg.UNITS_ASMKDLY = src.UNITS_ASMKDLY,
trg.RETAIL_ASMKDLY = src.RETAIL_ASMKDLY,
trg.UNITS_AS_PLN = src.UNITS_AS_PLN,
trg.RETAIL_AS_PLN = src.RETAIL_AS_PLN
when not matched then insert
(trg.asp,trg.ga, trg.pmm_styleid, trg.colorcode,trg.sizecode,trg.storenum,trg.week,trg.UNITS_ASLY,trg.RETAIL_ASLY ,trg.COST_ASLY , trg.UNITS_ASREGLY ,trg.RETAIL_ASREGLY ,
trg.UNITS_ASMKDLY ,trg.RETAIL_ASMKDLY ,trg.UNITS_AS_PLN ,trg.RETAIL_AS_PLN )
values
(src.asp,src.ga, src.pmm_styleid, src.colorcode,src.sizecode,src.storenum,src.week,src.UNITS_ASLY,src.RETAIL_ASLY,src.COST_ASLY,src.UNITS_ASREGLY,
src.RETAIL_ASREGLY, src.UNITS_ASMKDLY, src.RETAIL_ASMKDLY, src.UNITS_AS_PLN, src.RETAIL_AS_PLN);
The format for a merge statement is:
merge into <target_table> tgt
using <table_name or subquery> src
on (<join conditions between the target and source datasets>)
when matched then
update set ...
when not matched then
insert (...)
values (...);
Quite apart from the fact that your source subquery is incorrect (there are errors around where the t1 and t2 are; too many brackets, inappropriately trying to alias something etc), whilst you have join conditions inside your subquery, you're completely missing the ON clause for the merge itself.
You need to define the join conditions that match the data returned by your source subquery to your target table.
Now the error is : src.ga - Invalid Identifier
Although I have ga table in Trg table and src table .
merge into act_sls_0 trg using( select * from
(select a_0.asp, gadim.uic as ga, pmm_styleid, week, colorcode , sizecode, storenum, units_asly,retail_asly,
cost_asly ,units_asregly,retail_asregly,units_asmkdly,retail_asmkdly,units_as_pln,retail_as_pln
from act_sls
join dimension w on w.externalkey = 'W'||substr(WEEK,3,2)||'_'||substr(WEEK,5,2)
join a_0 on ( w.externalkey between startweek and endweek)
join dimension strdim on strdim.externalkey = (case when length(storenum) <= 4 then RPAD('STR-', 8 - length(storenum), '0') else 'STR-' END) || storenum
join store_info_0 str on store = strdim.uic
join dimension gadim on gadim.externalkey = decode(store_type, 'RETAIL', 'GA-01', 'ECOM', 'GA-02', '')
where trendweeks < 6)t1
join(select distinct asp, product, ga, color, sstyl_shade, pmm_styleid from aplc_1 aplc
join apc_1 apc using (asp,product,color)
where activeitem = 1 and ga!=0 and color != 0)t2
on (t1.asp = t2.asp and
t1.pmm_styleid = t2.pmm_styleid
and (case when length(t1.colorcode) <= 4 then RPAD('SHD-', 8 - length(t1.colorcode), '0') else 'SHD-' END) || t1.colorcode = t2.sstyl_shade
and t1.ga = t2.ga))src
on (trg.asp = src.asp and trg.pmm_styleid = src.pmm_styleid and trg.colorcode = src.colorcode and trg.ga = src.ga)
when matched THEN
update SET
trg.UNITS_ASLY = src.UNITS_ASLY,
trg.RETAIL_ASLY = src.RETAIL_ASLY,
trg.COST_ASLY = src.COST_ASLY,
trg.UNITS_ASREGLY = src.UNITS_ASREGLY,
trg.RETAIL_ASREGLY = src.RETAIL_ASREGLY,
trg.UNITS_ASMKDLY = src.UNITS_ASMKDLY,
trg.RETAIL_ASMKDLY = src.RETAIL_ASMKDLY,
trg.UNITS_AS_PLN = src.UNITS_AS_PLN,
trg.RETAIL_AS_PLN = src.RETAIL_AS_PLN
when not matched then insert
(trg.asp,trg.ga, trg.pmm_styleid, trg.colorcode,trg.sizecode,trg.storenum,trg.week,trg.UNITS_ASLY,trg.RETAIL_ASLY ,trg.COST_ASLY ,trg.UNITS_ASREGLY ,trg.RETAIL_ASREGLY ,
trg.UNITS_ASMKDLY ,trg.RETAIL_ASMKDLY ,trg.UNITS_AS_PLN ,trg.RETAIL_AS_PLN )
values
(src.asp,src.ga, src.pmm_styleid, src.colorcode,src.sizecode,src.storenum,src.week,src.UNITS_ASLY,src.RETAIL_ASLY,src.COST_ASLY,src.UNITS_ASREGLY,
src.RETAIL_ASREGLY, src.UNITS_ASMKDLY, src.RETAIL_ASMKDLY, src.UNITS_AS_PLN, src.RETAIL_AS_PLN);
commit;