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

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;

Related

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

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;

SQL update tableA.column where the column and value is in a separate table

I have tableA with the columns ID, ColumnHeader, Value.
I'm trying to update tableB where ID, and the value in tableB.ColumnHeader with tableB.Value.
Essentially, the column headers for tableB are in a column in Table A and not column headers themselves.
I'm stuck on specifying the table name. For example, how do I run this query when I only have tablename.____ where the blank is in a column in a separate table?
update tableB set table.____ .....
As seen in the screenshot below, in Table B, 4 should become 1, and 8 should become 2, and 12 should become 3. Thanks so much.
this is a example from Northwind database:
UPDATE dbo.Products
SET dbo.Products.CategoryID = c.CategoryID
FROM Products
INNER JOIN dbo.Categories c ON dbo.Products.CategoryID = c.CategoryID
I am not getting which table and column you want to update with which table and column.
also relationship is not clear.
This doesn't make sense to me. Are you trying to update table B or A? Are there like values in table B and A that you want updated?
The basic code is as shown below:
update tableb
set column id = 'value you're updating'
where column id = 'value you're looking for' --always make this unique like a key etc.

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

Update column in table with value from another

I need to update one column called Ident in table a to be a value from table b, as shown below. Both the change and keep values in table b are valid Idents which will appear in table a. I need to find the Change value in table b in table a, and then change the value in table a to the Keep value in table b.
Statement i'm using is:
update p set p.ident=t.keep
from pclscvq p inner join #tmp t on (p.ident=t.change)
where t.change=p.ident
Table B:
Change Keep
0004P 0004R
0004X 0004Y
00055 00056
00057 00058
0005B 0005C
0005K 0005L
0005Z 00060
00065 00066
0006X 0006Y
00070 00071
Very much stuck.
Using Advantage SQL

SQL Query - Ensure a row exists for each value in ()

Currently struggling with finding a way to validate 2 tables (efficiently lots of rows for Table A)
I have two tables
Table A
ID
A
B
C
Table matched
ID Number
A 1
A 2
A 9
B 1
B 9
C 2
I am trying to write a SQL Server query that basically checks to make sure for every value in Table A there exists a row for a variable set of values ( 1, 2,9)
The example above is incorrect because t should have for every record in A a corresponding record in Table matched for each value (1,2,9). The end goal is:
Table matched
ID Number
A 1
A 2
A 9
B 1
B 2
B 9
C 1
C 2
C 9
I know its confusing, but in general for every X in ( some set ) there should be a corresponding record in Table matched. I have obviously simplified things.
Please let me know if you all need clarification.
Use:
SELECT a.id
FROM TABLE_A a
JOIN TABLE_B b ON b.id = a.id
WHERE b.number IN (1, 2, 9)
GROUP BY a.id
HAVING COUNT(DISTINCT b.number) = 3
The DISTINCT in the COUNT ensures that duplicates (IE: A having two records in TABLE_B with the value "2") from being falsely considered a correct record. It can be omitted if the number column either has a unique or primary key constraint on it.
The HAVING COUNT(...) must equal the number of values provided in the IN clause.
Create a temp table of values you want. You can do this dynamically if the values 1, 2 and 9 are in some table you can query from.
Then, SELECT FROM tempTable WHERE NOT IN (SELECT * FROM TableMatched)
I had this situation one time. My solution was as follows.
In addition to TableA and TableMatched, there was a table that defined the rows that should exist in TableMatched for each row in TableA. Let’s call it TableMatchedDomain.
The application then accessed TableMatched through a view that controlled the returned rows, like this:
create view TableMatchedView
select a.ID,
d.Number,
m.OtherValues
from TableA a
join TableMatchedDomain d
left join TableMatched m on m.ID = a.ID and m.Number = d.Number
This way, the rows returned were always correct. If there were missing rows from TableMatched, then the Numbers were still returned but with OtherValues as null. If there were extra values in TableMatched, then they were not returned at all, as though they didn't exist. By changing the rows in TableMatchedDomain, this behavior could be controlled very easily. If a value were removed TableMatchedDomain, then it would disappear from the view. If it were added back again in the future, then the corresponding OtherValues would appear again as they were before.
The reason I designed it this way was that I felt that establishing an invarient on the row configuration in TableMatched was too brittle and, even worse, introduced redundancy. So I removed the restriction from groups of rows (in TableMatched) and instead made the entire contents of another table (TableMatchedDomain) define the correct form of the data.