PSQL - UPDATE tableA off tableB where Column1 Match - postgresql

I have a broken column with null values, however I have managed to import the data off a csv into TempTable
MediaRecords - localpath column is null
TempTable - localpath column is correct
UPDATE mediarecords
SET localpath = TempTable.localpath
FROM TempTable
WHERE recordid = TempTable.recordid;
I keep getting ERROR: relation "temptable" does not exist
LINE 3: FROM TempTable
however I can browse the table and see the data.
I tried following this How to update selected rows with values from a CSV file in Postgres? and here we are

Hu Bucky, can you check how the table is actually called because I see you referring at it as TempTable with camelcase and the error states temptable all lowercase.
PostgreSQL could be case sensitive. As example if you do the following
create table "TempTableABC" (id int);
Trying to select from temptableABC will fail
defaultdb=> select * from temptableABC;
ERROR: relation "temptableabc" does not exist
LINE 1: select * from temptableABC;
^
You'll need to use the same quoted syntax to make it work
defaultdb=> select * from "TempTableABC";
id
----
(0 rows)

UPDATE mediarecords
SET localpath = "TempTable".localpath
FROM public."TempTable"
WHERE "mediarecords".recordid = "TempTable".recordid;
Worked

Related

Update a column with row_number with duplicate records without PK

I have a table with duplicate records but without primary key. Data looks like this:
I want to update one empty column with one of column concatenate with row_number. After update, I want to achieve this:
Since the table does not have a unique column, which means I would join back to a CTE or subquery. I know in sql server, it can be done like this:
UPDATE X
SET X.NEW_KEY = X.PERSONNUMBER + '-' + X.NEW_CODE_DEST
FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY PERSONNUMBER) AS NEW_CODE_DEST,PERSONNUMBER,NEW_KEY
FROM EMPLOYEE
) as X;
I tried same logic in postgresql but it didn't work. It threw an error:
SQL Error [42P01]: ERROR: relation "x" does not exist
I also tried this in
UPDATE EMPLOYEE
SET NEW_KEY = X.PERSONNUMBER || '-' || X.NEW_CODE_DEST
FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY PERSONNUMBER) AS NEW_CODE_DEST,PERSONNUMBER
FROM EMPLOYEE
) as X;
The NEW_KEY is updated with duplicate value, not surprise there.
So is there a equivalent method in to achieve the same update result? Or I have my query wrong?
Really appreciate the help!

How to fix "ERROR: aggregate functions are not allowed in UPDATE"

I am trying to update a column based on a few conditions, using a calculation.
The theory I am using is as follows;
If column1 contains 'string' then 'calculation of column2 and column3' gets put in column4.
The calculation works, but I am struggling to find a way to UPDATE a column by using these IF conditions and a SUM.
I have searched stack and postgres documentation. I see that there are a number of aggregate errors but none specifically solve this problem.
UPDATE table1
SET "column4" = CASE
WHEN "column1" ILIKE '%Y%' THEN SUM(CAST("column2" AS
numeric(4,2))) / SUM(CAST("column3" AS numeric(4,2)))
END;
The error which I am getting is as follows;
ERROR: aggregate functions are not allowed in UPDATE
LINE 7: WHEN "column1" ILIKE '%Y%' THEN (SUM(CAST("...
Perform your calculations in a Common Table Expression:
WITH cte_avg AS (
SELECT SUM(CAST("column2" AS numeric(4,2))) / SUM(CAST("column3" AS numeric(4,2))) AS avg
FROM table1
)
UPDATE table1
SET "column4" = cte_avg.avg
FROM cte_avg
WHERE "column1" LIKE '%Y%'

Teradata MERGE with DELETE and INSERT - syntax?

I have been trying to find the correct syntax for the following case (if it is possible?):
MERGE INTO TAB_A tgt
USING TAB_B src ON (src.F1 = tgt.F1 AND src.F2 = tgt.F2
WHEN MATCHED THEN DELETE
ELSE INSERT (tgt.*) VALUES (src.*)
Background: the temp table contains a fix for the target table, as in it contains two types of rows:
the incorrect rows that are to be removed (they match with rows in the target table), and the 'corrected' row that should be inserted (it replaces all the 'delete' rows).
So essentially: remove anything that matches;
insert anything that does not match.
the current error I am getting is:
"Syntax error: expected something between the 'DELETE' keyword and the 'ELSE' keyword"
Any help appreciated, thanks!
You can make use of MultiStatement DELETE and INSERT statement to correct data from temp table into target table
DELETE FROM TAB_A WHERE EXISTS (SELECT 1 FROM TAB_B WHERE TAB_A.F1 = TAB_B.F1 AND TAB_A.F2 = TAB_B.F2)
;INSERT INTO TAB_A SELECT * FROM TAB_B;

Cast a PostgreSQL column to stored type

I am creating a viewer for PostgreSQL. My SQL needs to sort on the type that is normal for that column. Take for example:
Table:
CREATE TABLE contacts (id serial primary key, name varchar)
SQL:
SELECT id::text FROM contacts ORDER BY id;
Gives:
1
10
100
2
Ok, so I change the SQL to:
SELECT id::text FROM contacts ORDER BY id::regtype;
Which reults in:
1
2
10
100
Nice! But now I try:
SELECT name::text FROM contacts ORDER BY name::regtype;
Which results in:
invalid type name "my first string"
Google is no help. Any ideas? Thanks
Repeat: the error is not my problem. My problem is that I need to convert each column to text, but order by the normal type for that column.
regtype is a object identifier type and there is no reason to use it when you are not referring to system objects (types in this case).
You should cast the column to integer in the first query:
SELECT id::text
FROM contacts
ORDER BY id::integer;
You can use qualified column names in the order by clause. This will work with any sortable type of column.
SELECT id::text
FROM contacts
ORDER BY contacts.id;
So, I found two ways to accomplish this. The first is the solution #klin provided by querying the table and then constructing my own query based on the data. An untested psycopg2 example:
c = conn.cursor()
c.execute("SELECT * FROM contacts LIMIT 1")
select_sql = "SELECT "
for row in c.description:
if row.name == "my_sort_column":
if row.type_code == 23:
sort_by_sql = row.name + "::integer "
else:
sort_by_sql = row.name + "::text "
c.execute("SELECT * FROM contacts " + sort_by_sql)
A more elegant way would be like this:
SELECT id::text AS _id, name::text AS _name AS n FROM contacts ORDER BY id
This uses aliases so that ORDER BY still picks up the original data. The last option is more readable if nothing else.

Change column name from aggregate function default postgresql

I created a (big) table like so:
create table names_and_pics as (
select e.emp_name, e.dept, max(p.prof_pic)
from e.employees
left join profiles p
on e.emp_id = p.emp_id )
select * from names_and_pics;
emp_name | dept | max(p.prof_pic)
Dan | IT | 1234.img
Phil | HR | 3344.img
...
Because I forgot to give the 3rd field a name, I need to rename it now to "img_link" The syntax I've been trying is
alter table names_and_pics rename max(p.prof_pic) to img_link;
That gives the following error:
Syntax Error at or near "("
Any ideas how to fix this?
You need to put the column names in double quotes because it contains invalid characters:
alter table names_and_pics rename "max(p.prof_pic)" to img_link;
More about quoted identifiers in the manual
http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
Btw: the parentheses around the select in your create table ... as select statement are useless noise