populating null rows in table column based on matching IDs via join or otherwise - sql

Just to level set: i'm working within a Vertica database using SQL.
Let's say i have two tables: Table A and Table B. Let's also say that Table A is my final/master table used for data vis within Tableau (or something akin), and that Table B feeds certain columns into Table A based on matches within a tertiary table, Table C (which is not relevant to this conversation).
As is, Table A has columns:
ProgramName [varchar(50)]
CustomerName [varchar(50)]
Total_Cost [numeric(18,4)]
As is, Table B has columns:
CustomerCode [varchar(10)]
Total_Cost [numeric(18,4)]
What I would like to do is update Table A's CustomerName column to equal CustomerCode in Table B where the columns of total_cost_dollars equal each other across tables.
I've run this left join query to ensure that, when I do update Table A's CustomerName to equal CustomerCode, the total cost columns are exact/true matches for my entire data set.
SELECT
A.ProgramName,
A.CustomerName,
A.total_cost_dollars,
B.CustomerCode,
B.total_cost_dollars
FROM
TableA A
LEFT JOIN
TableB B
ON
B.total_cost_dollars = A.total_cost_dollars
WHERE
A.CustomerName IS NULL;
Any idea on how to solve this problem?

Since Vertica supports merge query, you can use merge statement:
merge into TableA A
using TableB B
ON (B.total_cost_dollars = A.total_cost_dollars)
when matched then
update
set
A.CustomerName = B.CustomerCode
where
A.CustomerName IS NULL;

Related

SQL - Updating table from other table selecting update row based on "priority" setting. (PostgreSQL 11.0)

I'm trying to update the 'ea' column from A with the value of 'ea' in table B.
Table A has 'cfn' and 'ea' and has unique product entries.
Table B has 'cfn' and 'ea' and 'dchain' and may have multiple entries for the same product (different dchain).
Table B 'dchain' field is linked to Table C which has 'dc' and a 'prio' setting (integer).
The record to select from table B to update table A needs to be based on the priority of table C.
I have tried multiple options with limit and order but somehow I'm missing the right sequence as the result is always wrong.....
If I understand correctly, you can get the values to update using:
select distinct on (b.cfn) b.*
from b join
c
on b.dchain = c.dc
order by b.cfn, c.priority;
Note: This assumes that lower priorities are more important. If higher priorities are add desc to the second key.
Then you can incorporate this into an update:
update a
set a.ea = bc.ea
from (select distinct on (b.cfn) b.*
from b join
c
on b.dchain = c.dc
order by b.cfn, c.priority
) bc
where bc.cfn = a.cfn;

Creating a result set of data using data from one table joining on another table containing two key columns

I'm trying to create a summarised result set joining two tables.
The first table (main and multi row) contains say the following columns:
trans_id,
trans_type_id
The second table (one row only) contains:
from_trans_type_id,
to_trans_type_id
I'm trying to join the two tables so that from_trans_type_id = trans_type_id and to_trans_type_id = trans_type_id and get the relevant trans_id values
I've tried self joining and derived joins to no effect.
The end result is that I'm looking to get a result set that looks something like this:
trans_id as from_trans_id, from_trans_type_id, trans_id as to_trans_id, to_trans_type_id
data is:
you can use join with multiple instance of firsttable
select b.trans_id as from_trans_id, from_trans_type_id, c.trans_id as to_trans_id, to_trans_type_id
from secondtable a
inner join firsttable b on a.from_trans_type_id=b.trans_type_id
inner join firsttable c on a.to_trans_type_id=c.trans_type_id

Assigning a value from one table to other table

There are two tables Table A and Table B. These contains the same columns cost and item. The Table B contains the list of items and their corresponding costs whereas the Table A contains only the list of items.
Now we need to check the items of Table A, if they are present in the Table B then the corresponging item cost should be assigned to the item's cost in Table A.
Can someone help me out by writing a query for this.
Consider the tables as shown:
Table A:
item cost
-------------
pen null
book null
watch null
Table B:
item cost
-------------
watch 1000
book 50
Expected output
Table A:
item cost
pen 0
book 50
watch 1000
Just add a foreign key (primary key of table A) in the Table B as you can say table A ID then add a join(right join may be) in the query to get or assign the prices respective items.
join be like
SELECT item, cost
FROM tablename a
RIGHT JOIN tablename b ON a.item= b.item;
Edit:
Just edit this table name ,now run it.
I would structure the update like this:
with cost_data as (
select
item,
max (cost) filter (where item = 'watch') as watch,
max (cost) filter (where item = 'book') as book
from table_b
group by item
)
update table_a a
set
watch = c.watch,
book = c.book
from cost_data c
where
a.item = c.item and
(a.watch is distinct from c.watch or
a.book is distinct from c.book)
In essence, I am doing a common table expression to do a poor man's pivot table on the Table B to get the rows into columns. One caveat here -- if there are multiple costs listed for the same item, this may not do what you want, but then you would need to know how to handle that in almost any case.
Then I am doing an "update A from B" against the CTE.
The last part is not critical, per se, but it is helpful -- to limit the query to only execute on rows that need to change. It's best to limit DML if it doesn't need to occur (the best way to optimize something is to not do it).
There are plenty of ways you could do this, if you are taking table b to be the one containing the price then a left outer join would do the trick.
SELECT
table_a.item,
CASE
WHEN table_b.cost IS NULL
THEN 0
ELSE table_b.cost
END as cost
FROM table_a
LEFT OUTER JOIN table_b ON table_a.item = table_b.item
The result also appears to suggest that pen which is not in table b should have a price of 0 (this is bad practice) but for the sake of returning the desired result you will want a case statement to assign a value if it is null.
In order to update the table, as per the comment
update table_a set cost = some_alias.cost
from (
SELECT
table_a.item,
CASE
WHEN table_b.cost IS NULL
THEN 0
ELSE table_b.cost
END as cost
FROM table_a
LEFT OUTER JOIN table_b ON table_a.item = table_b.item
) some_alias
where table_a.item = some_alias.item

How can I merge 2 access tables, keeping all data from table a and updated data from table b

Table A has a population of names and unique ids. Table B has the same unique ids and names. The majority of the names in table B are null, but some have an updated name. I want to merge the two tables so I get the old names from table A and new names from table B if they exist. Basically layer table B on top of table A to capture changes to the names.
I've done something like this in sas, but am having a problem in Access. merging via sas is no longer an option. can this be done in access?
You can do this in SQL using theIIFandISNULLfunctions to select the name from the correct table (from TableA if TableB is null, otherwise from TableB). If your tables has two fields:(id,the_name)a query could look like this:
SELECT a.id, IIF(ISNULL(b.the_name), a.the_name, b.the_name) AS the_name
INTO TableC
FROM TableA a
INNER JOIN TableB b ON a.id = b.id

Advanced sql query

I have two tables in a sql database, I am trying to update a column from my committed table (committedtbl) with values from my vendor table (vendortbl) based on a common column from both tables.
There is a column with the vendor identification number (vendorno) in both tables, I tried adding the vendor description (vendorname) column from the vendortbl to the committedtbl but there are no values in it.
I need to insert values into the vendorname based on the corresponding numbers from vendorno... How do I accomplish this?
The vendorname column already exists in my committedtbl.
I have tried this, but got an error:
update v_vendorname
set v_vendorname = v_vendorno
from vendortbl vt
where v_vendorno = vt.v_venkey
update committedtbl
set c.vendorname = v.vendorname
from committedtbl c
inner join vendortbl v on v.vendorno = c.vendorno