"Scalar subquery produced more than one element" - sql

I need to update a column's value by simply inserting a column of values according to another table in this way:
UPDATE `inbound-summit-278521.MET689.fact_posts`
SET `inbound-summit-278521.MET689.fact_posts`.accepted =
(SELECT (CASE WHEN id IN (SELECT T2.id
FROM `inbound-summit-278521.MET689.fact_posts` T1
JOIN `inbound-summit-278521.MET689.fact_posts` T2
ON T1.accepted_answer_id = T2.post_id)
THEN 1 ELSE 0 END)
FROM `inbound-summit-278521.MET689.fact_posts`)
WHERE `inbound-summit-278521.MET689.fact_posts`.accepted IS NULL;
The output error is shown as the title goes but no syntax error was detected. What did it go wrong? How should I fix it?

It is really hard to tell what you are trying to do. It seems to be that you want to set a flag to 1 if a corresponding row exists in the same table based on an "answer".
If so, you can use a correlated subquery. Something like this:
UPDATE `inbound-summit-278521.MET689.fact_posts` fp
SET accepted = 1
WHERE fp.accepted IS NULL AND
EXISTS (SELECT 1
FROM `inbound-summit-278521.MET689.fact_posts` fpa
WHERE fpa.accepted_answer_id = fp.post_id
);

Related

Updating all the record for a column in a table with value from another table

Hi I want to update all the values of RequestId column of IIL_CHANGE_REQUEST Table with the RequestId of TABLE_NAME_4MINS Table where REQUESTBY column in both tables are same. I am trying to do this in oracle daatabalse(sql developer)
My query:
Update IIL_CHANGE_REQUEST
set REQUESTID=(SELECT TABLE_NAME_4MINS.REQUESTID
FROM TABLE_NAME_4MINS
WHERE IIL_CHANGE_REQUEST.REQUESTBY = TABLE_NAME_4MINS.REQUESTBY)
WHERE EXISTS (SELECT TABLE_NAME_4MINS.REQUESTID
FROM TABLE_NAME_4MINS
WHERE IIL_CHANGE_REQUEST.REQUESTBY = TABLE_NAME_4MINS.REQUESTBY)
But every time I do this I get an error saying:
Error starting at line : 1 in command -
Update IIL_CHANGE_REQUEST
set REQUESTID=(SELECT TABLE_NAME_4MINS.REQUESTID
FROM TABLE_NAME_4MINS
WHERE IIL_CHANGE_REQUEST.REQUESTBY = TABLE_NAME_4MINS.REQUESTBY)
WHERE EXISTS (SELECT TABLE_NAME_4MINS.REQUESTID
FROM TABLE_NAME_4MINS
WHERE IIL_CHANGE_REQUEST.REQUESTBY = TABLE_NAME_4MINS.REQUESTBY)
Error report -
ORA-01427: single-row subquery returns more than one row
Please anyone help how can I do it.
It depends on what you want to do in such cases. If you don't really care, take any value, for example minimum:
update iil_change_request a
set a.requestid = (select min(b.requestid) --> here
from table_name_4mins b
where a.requestby = b.requestby)
where exists (select c.requestid
from table_name_4mins c
where a.requestby = c.requestby);
If that's not what you want, then you'll have to figure out what to do with those "duplicates". Perhaps you'll have to include yet another WHERE condition, or fix data, or ... who knows? I don't, while you should.
You need to find a condition to narrow down returned rows to the only per REQESTSTBY, for example you can replace ... with a column name in the query below to return just first row as per order-by:
MERGE INTO IIL_CHANGE_REQUEST r
USING (
SELECT *
FROM (
SELECT REQUESTBY, REQUESTID
,row_number()over(partition by REQUESTBY order by ...) rn
FROM TABLE_NAME_4MINS
)
where rn=1
) t
ON (r.REQUESTBY = t.REQUESTBY)
WHEN MATCHED THEN UPDATE
set REQUESTID=t.REQUESTID;

UPDATE with join referencing same table - Redshift SQL

Assume I have a table named tab. Tab has a field called "version". Version is sequential.
In Redshift, I would like to update rows in Tab with the value from a previous row. Please tell me how to do this. Essentially:
UPDATE tab
SET tab.fieldA = tabPrior.fieldA
FROM tab tabPrior
WHERE tab.version = tabPrior.version + 1;
I would love to use a JOIN, but this does not seem to work in Redshift.
To Update with a JOIN statement you are better off writing it in a subquery.
UPDATE table
SET
col1 = TT.col1
col2 = TT.col2
FROM (SELECT T1.id, T1.col1, T2.col2
FROM T1
JOIN T2 ON T1. id ON T2. id) AS TT
WHERE table.id = TT.id
Also, I noticed that your syntax is the SET is not correct:
SET fieldA = tabPrior.fieldA
Redshift does not allow for you to pass the table when selecting the column since it goes under the assumption that you are updating 1 table at a time.
SET column = One or more columns that you want to modify. Columns that
aren't listed retain their current values. Do not include the table
name in the specification of a target column. For example, UPDATE tab
SET tab.col = 1 is invalid.
Link: https://docs.aws.amazon.com/redshift/latest/dg/r_UPDATE.html

Oracle SQL Update one table column with the value of another table

I have a table A, where there is a column D_DATE with value in the form YYYYMMDD (I am not bothered about the date format). I also happen to have another table B, where there is a column name V_TILL. Now, I want to update the V_TILL column value of table B with the value of D_DATE column in table A which happens to have duplicates as well. Meaning, the inner query can return multiple records from where I form a query to update the table.
I currently have this query written but it throws the error:
ORA-01427: single-row subquery returns more than one row
UPDATE TAB_A t1
SET (V_TILL) = (SELECT TO_DATE(t2.D_DATE,'YYYYMMDD')
FROM B t2
WHERE t1.BR_CODE = t2.BR_CODE
AND t1.BK_CODE = t2.BK_CODE||t2.BR_CODE)
WHERE EXISTS (
SELECT 1
FROM TAB_B t2
WHERE t1.BR_CODE = t2.BR_CODE
AND t1.BK_CODE = t2.BK_CODE||t2.BR_CODE)
PS: BK_CODE IS THE CONCATENATION OF BK_CODE and BR_CODE
Kindly help me as I am stuck in this quagmire! Any help would be appreciated.
If the subquery returns many values which one do you want to use ?
If any you can use rownum <=1;
If you know that there is only one value use distinct
SET (V_TILL) = (SELECT TO_DATE(t2.D_DATE,'YYYYMMDD')
FROM B t2
WHERE t1.BR_CODE = t2.BR_CODE
AND t1.BK_CODE = t2.BK_CODE||t2.BR_CODE AND ROWNUM <=1)
or
SET (V_TILL) = (SELECT DISTINCT TO_DATE(t2.D_DATE,'YYYYMMDD')
FROM B t2
WHERE t1.BR_CODE = t2.BR_CODE
AND t1.BK_CODE = t2.BK_CODE||t2.BR_CODE)
above are workarounds. To do it right you have to analyze why you are getting more than one value. Maybe more sophisticated logic is needed to select the right value.
I got it working with this command:
MERGE INTO TAB_A A
USING TAB_B B
ON (A.BK_CODE = B.BK_CODE || B.BR_CODE
AND A.BR_CODE = B.BR_CODE AND B.BR_DISP_TYPE <> '0'
AND ((B.BK_CODE, B.BR_SUFFIX) IN (SELECT BK_CODE,
MIN(BR_SUFFIX)
FROM TAB_B
GROUP BY BK_CODE)))
As mentioned earlier by many, I was missing an extra condition and got it working, otherwise the above mentioned techniques work very well.
Thanks to all!

How can I update the value of multiple rows to a different specified value in the same column?

Say I have a table where there are product IDs, product desc., and the language of each desc. I would like it so that if there was a description with a NULL value for American-English, it would update to the British-English version of that the description for that product. Is there a way to do this using the update command in SQL?
I normally prefer this syntax for updating values in one table from values in another (or in this case the same) table, b/c it is easy to change the UPDATE...SET to a SELECT for testing and to quickly see what values would be updated.
UPDATE p_US
SET p_US.product_desc = p_GB.product_desc
FROM dbo.product p_US
INNER JOIN dbo.product p_GB ON p_US.productID = p_GB.productID
WHERE p_US.language_code = 'US'
AND p_GB.language_code = 'GB'
AND p_US.product_desc IS NULL
;
and then you can swap out the first two lines above with this for quick testing to see what would be updated:
SELECT p_US.productID, p_US.product,
oldDesc = p_US.product_desc, newDesc = p_GB.product_desc
update [table] set [column]= case [change factor] when '1' then 'X' else 'Y' end where [where clause]
Maybe:
UPDATE my_table SET desc=(SELECT desc from my_table WHERE my_table.id=id AND my_table.lang='british') WHERE lang='american' and desc is NULL;

Sybase update only the last record that fulfill conditions

I´m trying to update a record that fulfills some conditions but I need it to be the last one, I've read that I should use an order by and a limit. (I don't want to use a subquery to first fetch the last reccord that fulfill conditions ... I feel aint cool, should be a better way ...)
I've tried:
UPDATE table_1
SET some_field= 'value'
FROM table_1 t1
INNER JOIN table_2 t2 ON t1.field_1 = t2.field_1
WHERE t1.some_field = 'some_value' and t1.seome_other_field = 'some_other_value'
ORDER BY t1.some_field DESC limit 1
But I get Error (156) incorrect syntax near keyword 'ORDER'
For what I can see in Sybase docs I'm using the keywords in the correct order ...
http://infocenter.sybase.com/archive/index.jsp?topic=/com.sybase.infocenter.dc38151.1260/html/iqref/Update.htm
Am I breaking some rule ?
I´m sure is something pretty obvious ... but right now can't see it ...
Sybase 15.7.0.501.1011
With out using a subquery, or changing your query you could use set rowcount to limit the number of updates:
set rowcount 1
go
UPDATE table_1
SET some_field= 'value'
FROM table_1 t1, table_2 t2
WHERE t1.field_1 = t2.field_1
AND t1.some_field = 'some_value' and t1.seome_other_field = 'some_other_value'
ORDER BY t1.some_field DESC
go
set rowcount 0
go
This is a session level setting, and 0 is the default value to return all rows affected.