Update SQL Server two statements - sql

UPDATE ADDRESS
SET ADDRESS.LATITUDE = b.latitude,
ADDRESS.LONGITUDE= b.LONGITUDE
FROM POSTAL_CODE_LOOKUP b
WHERE ADDRESS.postal_cd = b.POSTALCODE
AND (address.LATITUDE != b.LATITUDE OR address.LONGITUDE !=b.LONGITUDE)
11:20:23 [BEGIN - 2454 row(s), 0.437 secs] Command processed
11:20:23 [BEGIN - 2454 row(s), 0.437 secs] Command processed
... 2 statement(s) executed, 4908 row(s) affected, exec/fetch time: 0.874/0.000 sec [2 successful, 0 warnings, 0 errors]
After executing the update I run the SQL below and get 2454 records.
select
a1.POSTAL_CD, b.POSTALCODE,
a1.LATITUDE, b.LATITUDE,
a1.LONGITUDE, b.LONGITUDE
from
ADDRESS a1, POSTAL_CODE_LOOKUP b
where
a1.postal_cd = b.postalcode
and (a1.LATITUDE != b.LATITUDE or a1.LONGITUDE != b.LONGITUDE);
Yes I have committed, and the records haven't changed. I don't understand why the update is being read as 2 statements. I don't understand why it's not updating.
How should I be writing this update statement?

Your ADDRESS table must have Update trigger, that's why there is a second statement about 2454 rows.
The amount updated is just 2454 rows, the same number You select after.

You have multiple rows in your join for one postal code i think

Use the below script to update the Address table .
UPDATE a
SET a.LATITUDE = b.latitude,
a.LONGITUDE= b.LONGITUDE
FROM [ADDRESS] a
JOIN POSTAL_CODE_LOOKUP b
ON a.postal_cd = b.POSTALCODE
WHERE (a.LATITUDE != b.LATITUDE or a.LONGITUDE !=b.LONGITUDE)

Related

Optimization of SQL join (between 40M and 240M rows) and case statements query

I am using Oracle SQL Developer and have this query that takes 5 input tables:
hit4 table that has 40M rows (used in join statement)
trx table that has 240M rows (used in join statement)
avg_hits_pk table with 1 float value (used in case statement)
avg_hits_npk table with 1 float value (used in case statement)
params that is 10 rows table with parameters (used is select as statement)
and it takes an endless amount of time. Is there anything that I can do to optimize this query?
SELECT DISTINCT
trx.trx_id,
hit4.customer_id,
1 as value_pattern,
hit4.trx_date,
trx.trx_amount,
role,
tiv,
tov,
ratio,
number_hits,
CASE
WHEN segment = 'PK' THEN round((SELECT avg_hits FROM avg_hits_pk))
ELSE round((SELECT avg_hits FROM avg_hits_npk))
END AS avg_hits,
(SELECT param_value FROM params WHERE param_name = 'CSTR') as CSTR,
trx.trx_type
FROM hit4
LEFT JOIN trx
ON hit4.customer_id = trx.customer_id AND hit4.trx_date = trx.trx_date
SOLVED
I added indexes to trx.trx_date and trx.customer_id, removed distinct from statement and filtered out hit4 table. Execution takes ~7 min. Thanks for help!
Further to the suggestion already given remove the SUBSELECT and see how is the performance.
SELECT
trx.trx_id,
hit4.customer_id,
1 as value_pattern,
hit4.trx_date,
trx.trx_amount,
role,
tiv,
tov,
ratio,
number_hits,
CASE
WHEN segment = 'PK' THEN round(avg_hits_pk.avg_hits)
ELSE round(avg_hits_npk.avg_hits)
END AS avg_hits,
params.param_value as CSTR,
trx.trx_type
FROM hit4,avg_hits_pk,avg_hits_npk,params
LEFT JOIN trx
ON hit4.customer_id = trx.customer_id AND hit4.trx_date = trx.trx_date
where params.param_name='CSTR';

Clickhouse join with condition

I found strange thing, the query:
SELECT *
FROM progress as pp
ALL LEFT JOIN links as ll USING (viewId)
WHERE viewId = 'a776a2f2-16ad-448a-858d-891e68bec9a8'
Result: 0 rows in set. Elapsed: 5.267 sec. Processed 8.62 million rows, 484.94 MB (1.64 million rows/s., 92.08 MB/s.)
Here modified query:
SELECT *
FROM
(SELECT *
FROM progress
WHERE viewId = 'a776a2f2-16ad-448a-858d-891e68bec9a8') AS p ALL
LEFT JOIN
(SELECT *
FROM links
WHERE viewId = toUUID('a776a2f2-16ad-448a-858d-891e68bec9a8')) AS l ON p.viewId = l.viewId;
Result : 0 rows in set. Elapsed: 0.076 sec. Processed 4.48 million rows, 161.35 MB (58.69 million rows/s., 2.12 GB/s.)
But it looks dirty.
Isn't it supposed to optimize the query considering where condition?
What is the right way to write the query here, and what if it will be where in?
Then I try to add another join:
SELECT *
FROM
(SELECT videoUuid AS contentUuid,
viewId
FROM
(SELECT *
FROM progress
WHERE viewId = 'a776a2f2-16ad-448a-858d-891e68bec9a8') p ALL
LEFT JOIN
(SELECT *
FROM links
WHERE viewId = toUUID('a776a2f2-16ad-448a-858d-891e68bec9a8')) USING `viewId`) ALL
LEFT JOIN `metaInfo` USING `viewId`,
`contentUuid`;
The result again very slow, considering that I want just join 3 tables with condition selection one row:
0 rows in set. Elapsed: 1.747 sec. Processed 9.13 million rows, 726.55 MB (5.22 million rows/s., 415.85 MB/s.)
At this moment the CH not very good cope with multi-joins queries (DB star-schema) and the query optimizer not good enough to rely on it completely.
So it needs to explicitly say how to 'execute' a query by using subqueries instead of joins.
Consider the test query:
SELECT table_01.number AS r
FROM numbers(87654321) AS table_01
INNER JOIN numbers(7654321) AS table_02 ON (table_01.number = table_02.number)
INNER JOIN numbers(654321) AS table_03 ON (table_02.number = table_03.number)
INNER JOIN numbers(54321) AS table_04 ON (table_03.number = table_04.number)
WHERE r = 54320
/*
┌─────r─┐
│ 54320 │
└───────┘
1 rows in set. Elapsed: 6.261 sec. Processed 96.06 million rows, 768.52 MB (15.34 million rows/s., 122.74 MB/s.)
*/
Let's rewrite it using subqueries to significantly speed it up.
SELECT number AS r
FROM numbers(87654321)
WHERE r = 54320 AND number IN (
SELECT number AS r
FROM numbers(7654321)
WHERE r = 54320 AND number IN (
SELECT number AS r
FROM numbers(654321)
WHERE r = 54320 AND number IN (
SELECT number AS r
FROM numbers(54321)
WHERE r = 54320
)
)
)
/*
┌─────r─┐
│ 54320 │
└───────┘
1 rows in set. Elapsed: 0.481 sec. Processed 96.06 million rows, 768.52 MB (199.69 million rows/s., 1.60 GB/s.)
*/
There are other ways to optimize JOIN:
use External dictionary to get rid of join on 'small'-table
use Join table engine
use ANY-strictness
use specific settings like join_algorithm, partial_merge_join_optimizations etc
Some useful refs:
Altinity webinar: Tips and tricks every ClickHouse user should know
Altinity webinar: Secrets of ClickHouse Query Performance
Isn't it supposed to optimize the query concidering where condition?
Such optimization is not implemented yet
It is expected behavior.
According to CH doc https://clickhouse.tech/docs/en/sql-reference/statements/select/join/#performance "When running a JOIN, there is no optimization of the order of execution in relation to other stages of the query. The join (a search in the right table) is run before filtering in WHERE and before aggregation."

Oracle SQL UPDATE SELECT with JOIN got error

Here is my SQL Query
UPDATE
(SELECT
*
FROM
web_fe_ipo_ipo_application apps
INNER JOIN web_fe_ipo_ipo_entry ipo ON apps.ipo_link_id = ipo.ipo_ref_number
WHERE
( ( apps.status = 0
OR ( apps.status = 2
AND apps.sub_status = 0
AND ipo.enable_omnibus_account = 1 ) )
AND ( apps.applied_qty BETWEEN 1 AND 10 )
AND apps.ipo_link_id = '984'
AND apps.latest = 1
AND ipo.latest = 1
AND apps.tranche_name = 'Public-1' )
ORDER BY
ipo_random(50)
FETCH FIRST 5 ROWS ONLY) selection
SET selection.initial_allot_qty = 5;
but it was not working well
I need to select random data from table then update after execute this query I got bellow error
Error at Command Line : 20 Column : 5
Error report -
SQL Error: ORA-01733: virtual column not allowed here
01733. 00000 - "virtual column not allowed here"
*Cause:
*Action:
Use a MERGE statement.
Here is an example:
MERGE INTO workers e
USING data_works h -- You can use the SELECT statement as well.
ON (e.f_id= h.f_id)
WHEN MATCHED THEN
UPDATE SET e.address= h.address
WHEN NOT MATCHED THEN
INSERT (f_id, address)
VALUES (h.f_id, h.address);
Here is your code. Hope it will work.
MERGE INTO web_fe_ipo_ipo_application apps
USING (SELECT * FROM web_fe_ipo_ipo_entry ipo ORDER BY
ipo_random)
ON(apps.ipo_link_id = ipo.ipo_ref_number)
WHEN MATCHED THEN
UPDATE SET apps.initial_allot_qty = 5
WHERE apps.status = 0
OR(apps.status = 2
AND apps.sub_status = 0
AND ipo.enable_omnibus_account = 1)
AND apps.applied_qty BETWEEN 1 AND 10
AND apps.ipo_link_id = '984'
AND apps.latest = 1
AND ipo.latest = 1
AND apps.tranche_name = 'Public-1'
AND rownum <=5;
Use the MERGE statement to select rows from one or more sources for INSERT or UPDATE operations in a table or view.
You can specify conditions to determine whether the target table or view is updated.
Merge operation is a convenient way to combine multiple operations. It allows you to avoid multiple INSERT, UPDATE, and DELETE DML statements as well.

Case Statement in SQL Query Issue

I'm trying to run a SQL query but an error happens when I run it.
Error:
[Code: -811, SQL State: 21000]
The result of a scalar fullselect, SELECT INTO statement, or VALUES INTO statement is more than one row..
SQLCODE=-811, SQLSTATE=21000, DRIVER=4.19.49
This is the SQL query that I am trying to run, I believe there is a problem with my CASE statement, I'm running out of solution. Please help, thanks a lot!
SELECT
ES.SHPMNT_REF,
(CASE
WHEN (ES.SERVICE_PROVIDER_NAME) IS NULL
THEN (SELECT BRDB.EXPORT_ONHAND.SERVICE_PROVIDER_NAME
FROM BRDB.EXPORT_ONHAND
WHERE BRDB.EXPORT_ONHAND.SHPMNT_REF = ES.SHPMNT_REF)
ELSE (ES.SERVICE_PROVIDER_NAME)
END) AS SP
FROM
BRDB.EXPORT_SHIPMENT ES
WHERE
ES.DATE_CREATE > CURRENT TIMESTAMP - 30 DAYS
I think this is what you are after. Joining on the table data you might need, then letting COALESCE check for null and get the other data if it is.
SELECT
ES.SHPMNT_REF,
COALESCE(ES.SERVICE_PROVIDER_NAME, OH.SERVICE_PROVIDER_NAME) AS SP
FROM BRDB.EXPORT_SHIPMENT ES
LEFT JOIN BRDB.EXPORT_ONHAND AS OH
ON ES.SHPMNT_REF = OH.SHPMNT_REF
WHERE
ES.DATE_CREATE > CURRENT TIMESTAMP - 30 DAYS
Maybe you should put inside the case:
THEN (SELECT TOP 1 BRDB.EXPORT_ONHAND.SERVICE_PROVIDER_NAME
The error is thrown because your subquery returns multiple values.
The best way would be joining the two table first and then get the value you need when the value is NULL.
That should work:
SELECT
ES.SHPMNT_REF
,CASE
WHEN ES.SERVICE_PROVIDER_NAME IS NULL
THEN EO.SERVICE_PROVIDER_NAME
ELSE ES.SERVICE_PROVIDER_NAME
END AS 'SP'
FROM BRDB.EXPORT_SHIPMENT ES
LEFT JOIN BRDB.EXPORT_ONHAND EO
ON ES.SHPMNT_REF = EO.SHPMNT_REF
WHERE ES.DATE_CREATE > CURRENT TIMESTAMP - 30 DAYS

What's wrong with this DB2 SQL Query?

SELECT
getOrgName(BC.ManageOrgID),
COUNT(CASE WHEN (EXISTS (SELECT FO.OBJECTNO FROM FLOW_OBJECT FO WHERE FO.ObjectNo=CR.SerialNo) AND NVL(CR.FinallyResult,'') IN ('01','02','03','04','05')) THEN BC.ManageOrgID ELSE NULL END)
FROM
BUSINESS_CONTRACT BC,
CLASSIFY_RECORD CR
WHERE
CR.ObjectType='BusinessContract'
AND CR.ObjectNo=BC.SerialNo
GROUP BY BC.ManageOrgID, CR.SerialNo, CR.FinallyResult
The error message I receive is:
11:01:32 [SELECT - 0 row(s), 0.000 secs] [Error Code: -112, SQL State: 42607] DB2 SQL Error: SQLCODE=-112, SQLSTATE=42607, SQLERRMC=SYSIBM.COUNT, DRIVER=3.57.82
... 1 statement(s) executed, 0 row(s) affected, exec/fetch time: 0.000/0.000 sec [0 successful, 0 warnings, 1 errors]
"The operand of the column function name (in your case, count) includes a column function, a scalar fullselect, or a subquery." DB2 doesn't allow this. See the documentation on SQL112 for more.
I'm not really sure how to fix your query but perhaps you can try the HAVING clause after GROUP BY.
Here is one way to rework the query:
SELECT
getOrgName( BC.ManageOrgID ),
COUNT( FO.ObjectNo ) AS objectcount
FROM BUSINESS_CONTRACT BC
INNER JOIN CLASSIFY_RECORD CR
ON CR.ObjectNo = BC.SerialNo
AND CR.ObjectType = 'BusinessContract'
AND CR.FinallyResult IN ( '01','02','03','04','05' )
INNER JOIN FLOW_OBJECT FO
ON FO.ObjectNo = CR.SerialNo
GROUP BY BC.ManageOrgID
;