I am working on a Teradata system in which I have 2 tables, Apple as A & Ball as B. Apple has 2 columns primId(integer) and updateValue(INteger). B only has primId(integer). What I am trying to do is, when A.primId=B.primId, then set updateValue=1 else to 0.
Table Apple:
Columns : Primary-key primId(Integer)
Other Columns : updateValue-(Integer)
Table Ball :
Columns : Primary-key primId(INteger)
My query so far :
update apple from apple a, ball b set updatevalue=1 where a.primId=b.primId;
I am getting a invalid query error, and I have no else clause yet. Any help would be nice.
Teradata doesn't support Outer Joins in an Update, but you could do it in FROM:
UPDATE apple
FROM
(
SELECT a.primId, CASE WHEN b.primId IS NULL THEN 0 ELSE 1 END AS x
FROM apple AS a
LEFT JOIN ball AS b
ON a.primId = b.primId
) AS src
SET upDateValue = src.x
WHERE apple.primId = src.primId
Probably more efficient:
UPDATE apple
SET upDateValue
= COALESCE((SELECT 1 FROM ball WHERE ball.primId = apple.primId),0);
But IMHO the best performing solution will be two Updates within a Multi Statement Request (MSR):
UPDATE apple
SET upDateValue = 1
WHERE EXISTS
( SELECT 1 FROM ball b WHERE apple.primId = b.primId)
;UPDATE apple
SET upDateValue = 0
WHERE updatevalue <> 1;
Please avoid implicit join syntax(comma separated) and use the appropriate syntax of joins:
UPDATE apple a
LEFT JOIN ball b
ON(a.primId=b.primId)
SET updatevalue= CASE WHEN b.primId is NULL THEN 0 ELSE 1 END ;
This query is a rather direct translation of your question:
update apple
set updatevalue = (case when exists (select 1 from ball b where apple.primId = b.primId)
then 1 else 0
end);
Can you please try this :
UPDATE a
FROM apple a
LEFT JOIN ball b ON a.id = b.id
SET a.updatevalue = CASE WHEN b.id > 0 THEN 1 ELSE 0 END
you are almost there. You just need to change alias.
update a
from apple a
left outer join ball b
on a.primId=b.primId
set updatevalue= (case when b.primId is not null then 1 else 0 end) ;
Try this.
Related
I am trying to do a case statement to update multiple columns, but only the first value from my join table AS 'b' is getting picked up. Below I have EDLCode = 1 and this value gets picked up. If I set the EDLCode = 2, it does not update anything. I can separate the updates into it's own blocks and those update correctly, but I was hoping to combine and make this code a little more condense. Any ideas?
UPDATE mainTable
SET
col_one = CASE WHEN EDLCode = 1 THEN b.Amount END,
col_two = CASE WHEN EDLCode = 2 THEN b.Amount END
FROM #mainDataTable AS a
INNER JOIN #deductLiabData AS b
ON a.Employee = b.Employee
WHERE b.EDLType = 'D'
Result would be:
EDLCode Amount
1 100
2 200
col_one col_two
100 null
This may be pointless but I want in ONE query to only the second value when Eligible equals 1, but always update the first value. So if the eligible is already 0 (or something else), don't update eligible. Can I do this in one query?
---Looping through this
UPDATE myTable p
SET p.first= 'C', p.eligible = 0
WHERE id = l_modifier_row_a.id
Desired Results
BEFORE
ID First Eligible
1 A 1
2 B 2
AFTER
ID First Eligible
1 C 0
2 C 2
In Oracle, you can use exists:
UPDATE myTable p
SET p.first = 'C',
p.eligible = 0
WHERE EXISTS (SELECT 1
FROM l_modifier_row_a l
WHERE p.id = l.id AND p.person_id = l.person_id
);
You cannot set a multiple column values sometime but not in others, in a single statement the columns are ALWAYS the same. However, you can conditionally set the value of a column to the existing value or change that value.
update mytable p
set first= 'C'
, eligible = case when p.eligible = 1
then 0
else p.eligible
end
where id = l_modifier_row_a.id ;
This might be doable in a single statement without a loop. But you did not post the loop control so I cannot look further.
I have this query in postgresql:
select *
from A s
join B m on (s.id=m.id)
where m.key=4 and s.ran=some_input_from_user
This gives me all the rows that I need to update.
I want to set A.value to be 90 for all these rows.
It doesn't look like a standart update query
if I do...
Update A set value=90 where.....
then I can't do the join.
any ideas how to do it?
This is the basic update syntax for PostgreSQL where you are updating based on a join to another table:
update A s
set
value = 90
from B m
where
s.id = m.id and
m.key = 4 and
s.ran = some_input_from_user
The trick is you never use the alias in the lvalue for the set commands. In other words, value = 90 is not s.value = 90. It seems minor, but I'm pretty sure it will prevent your query from working. The rationale is if you are updating table A (alias s) then any fields you are updating are, de-facto, from table A -- no need to alias them, and to allow aliases would almost imply you could update something other than A with this statement, which you cannot.
You can definitely use them in the rvalues, so this would certainly be okay (if it were your desire to update A based on B):
update A s
set
value = m.salary * s.commission
from B m
where
s.id = m.id and
(s.value is null or
s.value != m.salary * s.commission)
Here is the query:
update a set value = 90
where exists (
select 1 from b
where a.id = b.id and b.key=4
and a.ran=some_input_from_user);
The above query will eliminate the requirement of reading table a twice.
Also you can use this query:
update a set value = 90
where a.id in
(select b.id from b
where a.id = b.id and b.key = 4
and a.ran=some_input_from_user);
TRY THIS
UPDATE A
SET A.VALUE = 90
from A
join B m on (A.id=m.id)
where m.key=4 and s.ran=some_input_from_user
I have a table structure (particularly not fond of) where I need to update multiple colums in one row.
Source Table
ID TotalIntake TotalOutput Day
1 1000 500 0
1 1500 1000 1
2 100 200 0
Destination Table (should look like this after update)
ID TotalIntake_0 TotalIntake_1 TotalOutput_0 TotalOutput_1
1 1000 1500 500 1000
2 100 NULL 200 NULL
I tried to use Case when statement, but for some reason it only updates one of each columns and not all the columns across
UPDATE e
Set e.TotalIntake_0 = Case WHEN i.ProcedureDay = 0 Then i.TotalIntake End
,e.TotalIntake_1 = Case WHEN i.ProcedureDay = 1 Then i.TotalIntake End
,e.TotalOutput_0 = Case WHEN i.ProcedureDay = 0 Then i.TotalOutput End
,e.TotalOutput_1 = Case WHEN i.ProcedureDay = 1 Then i.TotalOutput End
FROM DestinationTable e LEFT JOIN SourceTable i ON e.id = i.id
Any ideas greatly appreciated!
Thanks!
Updates on a row are not cumulative. So, only one matching row is used for the update, and you don't know which one. You can do what you want but you need to summarize the rows first and then do the update:
UPDATE e
Set TotalIntake_0 = i.TotalIntake_0,
TotalIntake_1 = TotalIntake_1,
TotalOutput_0 = TotalOutput_0,
TotalOutput_1 = TotalOutput_1
FROM DestinationTable e LEFT JOIN
(select i.id,
TotalIntake_0 = max(Case WHEN i.ProcedureDay = 0 Then i.TotalIntake End),
TotalIntake_1 = max(Case WHEN i.ProcedureDay = 1 Then i.TotalIntake End),
TotalOutput_0 = max(Case WHEN i.ProcedureDay = 0 Then i.TotalOutput End),
TotalOutput_1 = max(Case WHEN i.ProcedureDay = 1 Then i.TotalOutput End)
from SourceTable i
group by i.id
) i
ON e.id = i.id ;
The documentation that describes this is a bit hard to parse:
Use caution when specifying the FROM clause to provide the criteria
for the update operation. The results of an UPDATE statement are
undefined if the statement includes a FROM clause that is not
specified in such a way that only one value is available for each
column occurrence that is updated, that is if the UPDATE statement is
not deterministic. For example, in the UPDATE statement in the
following script, both rows in Table1 meet the qualifications of the
FROM clause in the UPDATE statement; but it is undefined which row
from Table1 is used to update the row in Table2.
I've highlighted the relevant part.
Wouldn't it be simpler to do this in multiple updates?
UPDATE e
SET e.TotalIntake_0 = i.TotalIntake
FROM DestinationTable e
LEFT JOIN SourceTable i ON e.id = i.id
WHERE i.Day = 0
UPDATE e
SET e.TotalIntake_1 = i.TotalIntake
FROM DestinationTable e
LEFT JOIN SourceTable i ON e.id = i.id
WHERE i.Day = 1
Use transactions if necessary.
my question is, is it possible to select certain rows in a table according to a comparison rule without removing anything from the result. To clarify what i want to to imagine following example.
i have a table with two values,
A | B | C
1 0 hey
1 1 there
2 1 this
3 0 is
3 1 a
4 0 test
now i want to select the rows that have a 0 in the B column, and an a in the C column without removing the results that don't have a 0 in column B but the same value in column A.
For that i could do a
select C from T where A in (select A from T where B = 0);
but isn't it possible to select all C values where column B contains a 0 and that match column A with those?
I'd gladly stand by if more information is needed since it is a quite fuzzy question, but SQL can be confusing sometimes.
Tough to tell without your example result set; but maybe something like this:
SELECT A, B, C
FROM myTable
WHERE (B = 0 AND C LIKE '%A%')
OR (B <> 0 AND B = A)
I think you just want an or condition:
select C
from MyTable
where b = 0 or A in (select A from T where B = 0)
Is this the version you want:
select C
from MyTable
where C = 'a' or A in (select A from T where B = 0)