I want to update BRCD_NEW column in table branches with the condition applied on another column BRCD in the same table, here is my code, but it returns error
single-row subquery returns more than one row
update branches set brcd_new=(
select
case
when BRCD between '5000' and '5999' then CONCAT('PK001',BRCD)
else CONCAT('PK002',BRCD)
end
from branches);
You don't need the subquery to achieve what you are doing. Use CASE statement to get the value you need and assign in to your column in SET statement:
update branches
set brcd_new =
case
when BRCD between '5000' and '5999' then CONCAT('PK001',BRCD)
else CONCAT('PK002',BRCD)
end
-- WHERE <your filters (if needed)>
Related
I have a table that I want to update that contains a column called 'expiration_days'. What I am doing is trying to update the records in the 'expiration_days' column by using an 'alias column' (not sure what to call it) that is apart of a subquery where I calculated the number of days until a user's password has expired. The column from the subquery that I want to take the values from and update them in the actual table is called 'countdown'. I named the subquery results 'query' (derived table). So far I have this:
UPDATE LOGIN_INFO
SET expiration_days = query.countdown
FROM (
select li.name as name, countdown = 365 - datediff(day, sl.pwdate, getdate())
from master..syslogins sl, LOGIN_INFO li
where li.name = sl.name) query
WHERE LOGIN_INFO.name = query.name
The issue I am having is I get this error: You cannot use a derived table in the FROM clause of an UPDATE or DELETE statement. ( I also get: Incorrect syntax near ')' on the subquery where clause)
Is there a way I can take the results from the calculated column in a select statement and update the column in the LOGIN_INFO table in one query or some other easy clean way?
Perhaps something along the lines of:
update login_info
set expiration_days = (select 365 - datediff(day,s1.pwdate,getdate())
from master..syslogins s1
where s1.name = li.name)
from login_info li
where exists(select 1
from master..syslogins s2
where s2.name = li.name)
NOTES:
the exists() clause is added to insure we don't erroneously update a row in login_info that doesn't have a match in syslogins, otherwise OP will need to modify the logic accordingly (ie, what to set expiration_days to if a matching rows does not exist in syslogins?)
if syslogins.pwdate is NULLable (I don't have access to a running ASE instance at the moment) then OP will need additional logic to handle the scenario where s1.pwdate is NULL; default countdown to some hardcoded value? or perhaps modify the exists() to include the additional clause and s2.pwdate is not NULL?
I m struggling to update one column for a table with a sub query. I have a table where currently one of the values is null.
Currently I have:
UPDATE DW1_PURCHASES SET DW1_PURCHASES.TOTAL_AMT =
(
SELECT DW1_PURCHASES.QUANTITY * DW1_PRODUCTS.PRICE
FROM DW1_PURCHASES, DW1_PRODUCTS
WHERE DW1_PURCHASES.PRODUCT_ID = DW1_PRODUCTS.PRODUCT_ID
)
Although subquery returns data which I need to insert I get a error of single row subquery returns multiple rows.How do I basically shift subquery result to the table?
Thanks.
You don't have to JOINthe update table inside the sub-query. Just correlate the sub-query with update table
UPDATE DW1_PURCHASES
SET DW1_PURCHASES.TOTAL_AMT =
(
SELECT DW1_PURCHASES.QUANTITY * DW1_PRODUCTS.PRICE
FROM DW1_PRODUCTS
WHERE DW1_PURCHASES.PRODUCT_ID = DW1_PRODUCTS.PRODUCT_ID
)
Note : If your DW1_PRODUCTS table has duplicated PRODUCT_ID then even now there is a possibility to get the same error
I need to update a column in one table with the results from a select sub-query (and they should ultimately be different). But When I do this, I either get the exact same number for the hundreds of records, or I get the ORA-01427: single row sub-query returns more than one row query. error.
Can you please take a look and see what it is that I am overlooking? (I could just be overlooking something simple for all I know)
UPDATE WD_PRODUCT_CLASS
SET CURRENT_CASES = ( WITH STUFF_COUNT AS
(
SELECT sum(CURRENT_DETAIL.COMBINED_QTY) AS TOTAL_CASES
FROM CURRENT_DETAIL, SKU_MAJORS, WD_PRODUCT_CLASS
WHERE CURRENT_DETAIL.LOC_ID =
&PARM_LOC_ID
AND CURRENT_DETAIL.INVEN_ID = SKU_MAJORS.INVEN_ID
AND WD_PRODUCT_CLASS.CATEGORY = SKU_MAJORS.CONT_DESC
GROUP BY WD_PRODUCT_CLASS.CATEGORY
)
(
SELECT SUM(Z.TOTAL_CASES) FROM STUFF_COUNT Z
)
);
Maybe you need someting like this:
UPDATE WD_PRODUCT_CLASS wpc
SET wpc.CURRENT_CASES = (
SELECT sum(cd.COMBINED_QTY)
FROM CURRENT_DETAIL cd join SKU_MAJORS sm ON cd.INVEN_ID = sm.INVEN_ID
WHERE cd.LOC_ID = &PARM_LOC_ID
AND sm.CONT_DESC = wpc.CATEGORY
)
WHERE 1=1; -- if you don't set a condition all the rows will be updated
Your query updates the table with the same values because you're using a not correlated subquery in the SET clause. This subquery don't depends on the parent query, so it's calculated only once.
I suppose you need a correlated subquery so I changed your update + removed some extra parts.
I have one table with the following columns:
T_RESOLVED_DATE
I_HOUSEHOLD_NUMBER
I_RESOLVED_SET_NUMBER
I_STATION_CODE
I_RESOLVED_START_MIN
I_DURATION
I_PERSON_NUMBER
I_COVIEW_DEMO_ID
Initially, I_COVIEW_DEMO_ID is set to null.
Then I have another table with the following columns:
T_RESOLVED_DATE
I_HOUSEHOLD_NUMBER
I_PERSON_NUMBER
I_AGE
T_GENDER
I_COVIEW_DEMO_ID
I am trying to update I_COVIEW_DEMO_ID in the first table by using the value of I_COVIEW_DEMO_ID in the second table where the T_RESOLVED_DATE, I_HOUSEHOLD_NUMBER, and I_PERSON_NUMBER are equal in both tables. The first table may contain multiple rows with the same DATE, HOUSEHOLD_NUMBER, and PERSON_NUMBER, because the rows can vary by the rest of the columns.
I have tried to do a select and a group by which seems to get me part way there, but I am getting a "single-row subquery returns more than one row" error when I try to update the columns in the first table. This is what I've tried, along with variations of it:
UPDATE
Table1
SET
I_COVIEW_DEMO_ID =
(SELECT
b.I_COVIEW_DEMO_ID
FROM Table1 a,
Table2 b
WHERE a.I_HOUSEHOLD_NUMBER = b.I_HOUSEHOLD_NUMBER AND
a.I_PERSON_NUMBER = b.I_PERSON_NUMBER AND
a.T_RESOLVED_DATE = b.T_RESOLVED_DATE
GROUP BY b.I_COVIEW_DEMO_ID);
Any suggestions?
I was able to get it to work using this statement:
MERGE INTO table1 a
USING
(
SELECT DISTINCT
T_RESOLVED_DATE,
I_HOUSEHOLD_NUMBER,
I_PERSON_NUMBER,
I_COVIEW_DEMO_ID
FROM
table2
) b
ON
(
a.T_RESOLVED_DATE = b.T_RESOLVED_DATE
AND a.I_HOUSEHOLD_NUMBER = b.I_HOUSEHOLD_NUMBER
AND a.I_PERSON_NUMBER = b.I_PERSON_NUMBER
) WHEN MATCHED THEN
UPDATE SET
a.I_COVIEW_DEMO_ID = b.I_COVIEW_DEMO_ID;
As per our discussion on the comments this would be a simple PLSQL block to do what you need. I'm doing direct from my head without test, so you may need to fix some sintaxe mistake.
BEGIN
FOR rs IN ( SELECT I_HOUSEHOLD_NUMBER,
I_PERSON_NUMBER,
I_COVIEW_DEMO_ID,
T_RESOLVED_DATE
FROM Table2 ) LOOP
UPDATE Table1
SET I_COVIEW_DEMO_ID = rs.I_COVIEW_DEMO_ID
WHERE I_PERSON_NUMBER = rs.I_PERSON_NUMBER
AND I_HOUSEHOLD_NUMBER = rs.I_HOUSEHOLD_NUMBER
AND T_RESOLVED_DATE = rs.T_RESOLVED_DATE;
END LOOP;
--commit after all updates, if there is many rows you should consider in
--making commits by blocks. Define a count and increment it whithin the for
--after some number of updates you commit and restart the counter
COMMIT;
END;
I am newbie to teradata.
I need to delete a row once the case condition is satisfied.
Eg: case condition true delete the selected row.
Maybe I am misinterpreting what you are trying to accomplish with the CASE statement, but based on my understanding you can use the WHERE clause to conditionally remove data from a table:
DELETE
FROM MyDB.MyTable
WHERE Col1 = 31
AND "Desc" = 'xxxxxx';
EDIT:
Based on your comment then you need to apply the CASE logic to each column returned in the SELECT statement that you wish to obscure.
SELECT CASE WHEN Col1 = 31 and "DESC" = 'yyyyy'
THEN NULL
ELSE ColA
END AS ColA_,
/* Repeat for each column you wish to "delete" */
FROM MyDB.MyTable;