I am trying to update some values in the table by multiplying the t1 values to t2 values. Here is the query I wrote to update the data. For some reasons it's taking long time to update the values. Can I have some simplified query to update the same data to improve the performance of query?
update dm_digital_media.dim_dummy sub
set sub.SUBS_ONE_TIME_TOTAL_USD = sub.SUBS_ONE_TIME_TOTAL_LOCAL_CURR * nvl(exch.exchange_rate,1)
from dm_digital_media.dim_dummy sub1
inner join dm_digital_media.rate_dim exch on exch.exchange_source = sub1.currency
where sub.START_DATE < '2018-01-01'
and exch.exchange_target = 'USD'
and exch.begin_effect_date = '2018-01-01'
and exch.exchange_period = 'Monthly';
Could you pls try below SQL? I modified it a bit with CTE.
with exch as (
select exchange_source,nvl(exch.exchange_rate,1) exchange_rate from dm_digital_media.rate_dim exch where exch.exchange_target = 'USD' and exch.begin_effect_date = '2018-01-01' and exch.exchange_period = 'Monthly'
)
update dm_digital_media.dim_dummy sub set sub.SUBS_ONE_TIME_TOTAL_USD = sub.SUBS_ONE_TIME_TOTAL_LOCAL_CURR * exchange_rate
from dm_digital_media.dim_dummy sub1
inner join exch on exch.exchange_source = sub1.currency
where sub.START_DATE < '2018-01-01' ;
Related
i have update query but when i execute the quesry it take a long time to execute until it success. i dont know whats wrong. i run in dbeaver is there anyway to execute the quesry without waiting too long ?
update m_deposit_account_term_and_preclosure
set last_accrued_amount = (select amount from acc_gl_journal_entry where entry_date = (select max(entry_date) from acc_gl_journal_entry) and entity_id = sa.id and type_enum = 2 and description = 'Accrual Deposit Interest Expense End Of Month')
from m_savings_account sa
where sa.id = m_deposit_account_term_and_preclosure.savings_account_id;
As written, the update is executing the subquery on a row by row basis. That's going to be very slow, indeed.
Changing to a set-based operation by joining your tables first will improve overall performance, but if you have a lot of rows to update, it could still take a long time. Adding a WHERE clause will help, but it's entirely dependent on your tables.
MySQL:
UPDATE
m_deposit_account_term_and_preclosure as da
JOIN
m_savings_account as sa
ON sa.id = da.savings_account_id
JOIN
(
SELECT
entity_id,
amount
FROM acc_gl_journal_entry
WHERE entry_date = (
SELECT max(entry_date)
FROM acc_gl_journal_entry
)
AND entity_id = sa.id
AND type_enum = 2
AND description = 'Accrual Deposit Interest Expense End Of Month'
) as amt
SET da.last_accrued_amount = amt.amount
WHERE da.last_accrued_amount <> amt.amount;
SQL Server:
UPDATE da
SET last_accrued_amount = amt.amount
FROM
m_deposit_account_term_and_preclosure as da
JOIN
m_savings_account as sa
ON sa.id = da.savings_account_id
JOIN
(
SELECT
entity_id,
amount
FROM acc_gl_journal_entry
WHERE entry_date = (
SELECT max(entry_date)
FROM acc_gl_journal_entry
)
AND entity_id = sa.id
AND type_enum = 2
AND description = 'Accrual Deposit Interest Expense End Of Month'
) as amt
WHERE da.last_accrued_amount <> amt.amount;
I am trying to iterate over a Temporary Table inside of a Function, where I want to make an Update on every row.
The Temporary Table should hold all the user ID's that are getting out of the query.
After that, for every Single User it should be checked, if the percentage of the transactions with attributes is smaller than 50% of all transactions.
In the end, the account field master_segments should be updated.
My Code looks like that:
CREATE OR REPLACE FUNCTION temptable()
RETURNS VARCHAR
AS $$
BEGIN
CREATE TEMP TABLE IF NOT EXISTS testTable AS
SELECT account.sfid, transactions.transactionNumber
FROM account
INNER JOIN transactions ON account.sfid =transactions.accountsfid
INNER JOIN transactionLineItems ON transactions.transactionNumber = transactionLineItems.transactionNumber
INNER JOIN products ON transactionLineItems.USIM = products.USIM
WHERE account.gender = '1' AND (transactions.transactionDate >= current_date - interval '730' day AND products.gender = 'female' AND products.agegroup = 'adult');
FOR j IN testTable.sfid LOOP
SELECT(
(SELECT COUNT(transactions.transactionNumber)
FROM transactions
INNER JOIN account ON account.sfid = transactions.accountsfid
INNER JOIN transactionLineItems ON transactions.transactionNumber = transactionLineItems.transactionNumber
INNER JOIN products ON transactionLineItems.USIM = products.USIM
WHERE products.gender = 'male' AND products.agegroup = 'adult' AND transactions.transactionDate >= current_date - interval '730' day)*1.0 /
(SELECT COUNT(transactions.transactionNumber)
FROM transactions
WHERE transactions.transactionDate >= current_date - interval '730' day)
) < 0.5;
UPDATE account
SET account.master_segments = 'Women' WHERE account.sfid = testTable.sfid;
END LOOP;
END;
$$ LANGUAGE plpgsql;
I am getting this message:
ERROR: syntax error at or near "testTable"
LINE 14: FOR j IN testTable.sfid LOOP
Does someone has a suggestion on this?
Thanks!
I assume what you try to do is:
UPDATE account
SET account.master_segments = 'Women'
FROM (
SELECT account.sfid, transactions.transactionNumber
FROM account
INNER JOIN transactions ON account.sfid =transactions.accountsfid
INNER JOIN transactionLineItems ON transactions.transactionNumber = transactionLineItems.transactionNumber
INNER JOIN products ON transactionLineItems.USIM = products.USIM
WHERE account.gender = '1' AND (transactions.transactionDate >= current_date - interval '730' day AND products.gender = 'female' AND products.agegroup = 'adult')
) testtable
WHERE account.sfid = testtable.sfid
You don't need a subquery and you don't need to repeat the account table for this logic:
UPDATE account a
SET master_segments = 'Women'
FROM transactions t INNER JOIN
transactionLineItems tli
ON t.transactionNumber = tli.transactionNumber AND
t.transactionDate >= current_date - interval '730' day INNER JOIN
products p
ON tli.USIM = p.USIM AND
p.gender = 'female' AND
p.agegroup = 'adult'
WHERE a.gender = '1' AND a.sfid = t.sfid;
I also introduced table aliases so the query is easier to write and to read.
UPDATE Newchat
Set [Answered] = (Select b.[Answered]
From Table1 b
where Newchat.CHAT_ID = b.[Chat ID]
and Newchat.Chat_Date >= '2017-Feb-22' and Newchat.Chat_Date <= '2017-Feb-28');
Whenever I'm running this code all rows of [Answered] are getting Null except this dates.
Please suggest someway.
I also tried applying filter "Newchat.[Answered] is not null"
UPDATE Newchat
Set [Answered] = (Select b.[Answered]
From Table1 b
where Newchat.CHAT_ID = b.[Chat ID] and Newchat.[Answered] is not null
and Newchat.Chat_Date >= '2017-Feb-22' and Newchat.Chat_Date <= '2017-Feb-28');
This too doesn't work.
When there is no match, you get NULL. Presumably you really want:
UPDATE nc
Set [Answered] = b.[Answered]
From NewChat nc join
Table1 b
on nc.CHAT_ID = b.[Chat ID] and
nc.Chat_Date >= '2017-Feb-22' and nc.Chat_Date <= '2017-Feb-28';
This only updates the rows that match the conditions.
You have two queries going on here. The inner one (inside the brackets) is supplying the data for the outer one which is doing the update. Your problem is that the inner query is restricted by dates, so it only supplies values for those dates. But the outer query updates all rows - with NULL where there is no data from the inner query.
Keeping close to the way you have set out your query, moving the date restrictions outside the brackets should give you what you want - like this:
UPDATE Newchat
Set [Answered] = ( Select b.[Answered]
From Table1 b
where Newchat.CHAT_ID = b.[Chat ID] )
WHERE Newchat.Chat_Date >= '2017-Feb-22' and Newchat.Chat_Date <= '2017-Feb-28';
Try below UPDATE statement:
UPDATE Newchat SET [Answered] = b.[Answered]
From Table1 b
WHERE Newchat.CHAT_ID = b.[Chat ID] AND DATEDIFF(DAY,Newchat.Chat_Date,'2017-
02-22') <= 0 AND DATEDIFF(DAY,Newchat.Chat_Date,'2017-02-28') >= 0
I'm trying to update a temp table with a rolling average calculation (MS Access 2010.)
As a select query, this works to calculate a 3 month rolling average but is slow so I'd rather have the values stored and updated only when necessary:
SELECT tempQORDistGrouped.Type, tempQORDistGrouped.Supplier, tempQORDistGrouped.DepBkMo, tempQORDistGrouped.Amt, tempQORDistGrouped.Brands, tempQORDistGrouped.T2, tempQORDistGrouped.Brand, (select avg(rolavg.Amt) from tempQORDistGrouped as rolavg
where rolavg.Type = tempQORDistGrouped.Type
and rolavg.Supplier = tempQORDistGrouped.Supplier
and rolavg.Brands = tempQORDistGrouped.Brands
and rolavg.Brand = tempQORDistGrouped.Brand
and rolavg.DepBkMo between dateadd("m",-2,tempQORDistGrouped.DepBkMo) and tempQORDistGrouped.depbkmo) AS AvgAmt
FROM tempQORDistGrouped;
I've tried the update query below but I think my inner join syntax is bad as it won't recognize x1.Type as a valid field (do I need to include these as part of the inner join fields rather than in the where clause??):
UPDATE tempQORDistGrouped AS x1
INNER JOIN (SELECT itmID, avg(Amt) AS RolAvg
FROM tempQORDistGrouped
WHERE tempQORDistGrouped.Type = x1.Type
AND tempQORDistGrouped.Brand = x1.Brand
AND tempQORDistGrouped.Brands = x1.Brands
AND tempQORDistGrouped.T2 = x1.T2
AND tempQORDistGrouped.DepBkMo between dateadd("m",-2,x1.DepBkMo) and x1.DepBkMo
GROUP BY itmID
) AS x2
ON x1.itmID = x2.itmID
SET x1.3MonthRollingAmt = x2.RolAvg;
Cheers
Untested but should work.
I am doing a column level query to calculated the AVG and then mapping it back to the rest of the columns
Try this:
UPDATE tempQORDistGrouped AS x1
INNER JOIN (
SELECT itmID
, (
SELECT avg(Amt) amt
FROM tempQORDistGrouped x4
WHERE x4.Type = x3.Type
AND x4.Brand = x3.Brand
AND x4.Brands = x3.Brands
AND x4.T2 = x3.T2
AND x4.DepBkMo BETWEEN dateadd("m", - 2, x3.DepBkMo) AND x3.DepBkMo
) AS RolAvg
, x3.Brand
, x3.Brands
, x3.DepBkMo
, x3.T2
FROM tempQORDistGrouped x3
) AS x2
ON x1.itmID = x2.itmID
AND x1.Brand = x2.Brand
AND x1.Brands = x2.Brands
AND x1.T2 = x2.T2
AND x1.DepBkMo BETWEEN dateadd("m", - 2, x2.DepBkMo) AND x2.DepBkMo
SET x1.3MonthRollingAmt = x2.RolAvg;
I'm doing a weight reporting and I have a problem. I use this query to know the enters of weight in our warehouse, but when there are no transactions in a date this date doesn't appears in the results.
SELECT erp.MKPF.BUDAT AS Data,
Sum( erp.MSEG.MENGE * erp.MARM.BRGEW ) as pes
From erp.MKPF
INNER Join erp.MSEG on erp.MKPF.MANDT = erp.MSEG.MANDT and erp.MKPF.MBLNR = erp.MSEG.MBLNR
INNER Join erp.MARM on erp.MSEG.MANDT = erp.MARM.MANDT and erp.MSEG.MATNR = erp.MARM.MATNR And erp.MSEG.MEINS = erp.MARM.MEINH
INNER JOIN erp.MARA on erp.MSEG.MANDT = erp.MARA.MANDT and erp.MSEG.MATNR = erp.MARA.MATNR
WHERE erp.MKPF.MANDT = '100'
and erp.MKPF.BUDAT >= '20120720'
and erp.MKPF.BUDAT <= CONVERT(VARCHAR(8), GETDATE(), 112) -1
and erp.MSEG.LGORT in ('1001','1069')
and erp.MSEG.BWART In ('101','102','311','312')
and erp.MSEG.WERKS = '1001'
and erp.MARA.MTART in ('Z001','Z010','Z002','Z02E')
GROUP BY erp.MKPF.BUDAT*
Now the results are like this:
Data PES
20120720 9999999.9999
20120721 9999999.8888
20120723 9999999.7777
And i need this
Data PES
20120720 9999999.9999
20120721 9999999.8888
20120722 0
20120723 999999.7777
Can somebody help me?
Use a table or a view to generate the date range of interest and let this drive the query. Then you outer join your results to this view. This can be done dynamically in the query. For example, in Oracle, you can use "connect by" to generate a series:
create table my_summary(the_day date, pes number);
insert into my_summary values(to_date('20120720', 'yyyymmdd'), 9999999.9999);
insert into my_summary values(to_date('20120721', 'yyyymmdd'), 9999999.8888);
insert into my_summary values(to_date('20120723', 'yyyymmdd'), 9999999.7777);
SELECT d.the_day, NVL(s.pes, 0) AS pes
FROM ( SELECT to_date('20120720', 'yyyymmdd') + level -1 AS the_day
FROM dual CONNECT BY level <= 4) d
LEFT OUTER JOIN my_summary s ON (d.the_day = s.the_day)
ORDER BY 1
THE_DAY PES
--------- ---
20-JUL-12 9999999.9999
21-JUL-12 9999999.8888
22-JUL-12 0
23-JUL-12 9999999.7777
Other rdbms have other methods to generate a series. This will require you to know the start date you want, and the number of records (in the example above 20120720 and 4).
Thanks to all, finally I did this and it works
SELECT
c.BUDAT AS DATA,
CASE When SAP.pes Is Null then '0'
ELSE SAP.pes
END
From
erp.YSD_CALENDAR as c LEFT JOIN
(SELECT
erp.MKPF.BUDAT,
Sum(
erp.MSEG.MENGE
* erp.MARM.BRGEW ) as pes
FROM
erp.MKPF
INNER Join erp.MSEG on erp.MKPF.MANDT = erp.MSEG.MANDT and erp.MKPF.MBLNR = erp.MSEG.MBLNR
INNER Join erp.MARM on erp.MSEG.MANDT = erp.MARM.MANDT and erp.MSEG.MATNR = erp.MARM.MATNR And erp.MSEG.MEINS = erp.MARM.MEINH
INNER JOIN erp.MARA on erp.MSEG.MANDT = erp.MARA.MANDT and erp.MSEG.MATNR = erp.MARA.MATNR
WHERE
erp.MKPF.MANDT = '100'
and erp.MKPF.BUDAT >= '20120720'
and erp.MSEG.LGORT in ('1001','1069')
and erp.MSEG.BWART In ('101','102','311','312')
and erp.MSEG.WERKS = '1001'
and erp.MARA.MTART in ('Z001','Z010','Z002','Z02E')
and erp.MSEG.SHKZG = 'S'
GROUP BY erp.MKPF.BUDAT
) SAP ON SAP.BUDAT = c.BUDAT
WHERE
c.BUDAT >= '20120720'
and c.BUDAT <= CONVERT(VARCHAR(8), GETDATE(), 112)
GROUP BY c.BUDAT, SAP.pes
ORDER BY c.BUDAT