FROM clause with DO UPDATE in Postgres - postgresql

I am writing a upsert query using CONFLICT. But I am facing issue on update part. Here is my query looks like.
INSERT INTO
customers (name, email, city)
SELECT
'jack',
'jack#io' as email,
city
FROM
customers
where
id = 1
ON CONFLICT(name) DO
update
set
email = cs.email
FROM
(
select
email
from
customers
where
id = 1
)
as cs;
following is query structure
CREATE TABLE customers (
id serial PRIMARY KEY,
name VARCHAR UNIQUE,
email VARCHAR NOT NULL,
city VARCHAR NOT NULL
);
Erro i am getting
syntax error at or near "FROM"
LINE 1: ... ON CONFLICT(name) DO update set email = cs.email FROM (sele...

Your sub-select has the wrong structure.
If you need to update multiple columns, use a tuple assignment
INSERT INTOcustomers (name, email, city)
SELECT 'jack',
'jack#io' as email,
city
FROM customers
where id = 1
ON CONFLICT(name) DO
update set (email, other_col) = (select email, c2
from customers
where id = 1)

Related

I'm trying to derive a result table from a input table and condition table in postgresql

This is the code but I'm getting errors while compiling :
The condition table permissions can be changed if pleased that's why I'm adding the permissions column, the result table needs a permission column for all the users according to the values of condition table
-- create
CREATE TABLE EMPLOYEE (
empId INTEGER PRIMARY KEY,
username TEXT NOT NULL,
userrole TEXT NOT NULL,
roles TEXT NOT NULL,
accesses TEXT NOT NULL
);
-- insert
INSERT INTO EMPLOYEE VALUES (0001, 'Clark','President', 'Admin','privileged');
INSERT INTO EMPLOYEE VALUES (0002, 'Dave','sales rep', 'Operational role','not privileged');
INSERT INTO EMPLOYEE VALUES (0003, 'Ava','finance manager', 'Managerial role','privileged');
-- fetch
SELECT * FROM EMPLOYEE;
--mastertable
CREATE TABLE CONDITION (
userrole TEXT NOT NULL,
accesses TEXT NOT NULL,
permissions TEXT NOT NULL
);
--insertintomastertable
INSERT INTO CONDITION VALUES ('admin','privileged','granted');
INSERT INTO CONDITION VALUES ('admin','privileged','revoked');
INSERT INTO CONDITION VALUES ('Managerial role','not privileged','granted');
INSERT INTO CONDITION VALUES ('Managerial role','privileged','revoked');
INSERT INTO CONDITION VALUES ('Operational role','not privileged','granted');
INSERT INTO CONDITION VALUES ('Operational role','privileged','revoked');
--resulttable
CREATE TABLE RESULT (
empId INTEGER PRIMARY KEY,
username TEXT NOT NULL,
userrole TEXT NOT NULL,
roles TEXT NOT NULL,
permission TEXT
);
--insertintoresult
INSERT INTO RESULT (empId, username, userrole, roles)
SELECT empId, username, userrole, roles
FROM EMPLOYEE;
DO
$do$
BEGIN
IF (EMPLOYEE.roles and EMPLOYEE.accesses) == (CONDITION.roles and CONDITION.accesses) THEN
RESULT.permission := 'GRANTED';
WHERE (EMPLOYEE.roles and EMPLOYEE.accesses) == (CONDITION.roles and CONDITION.accesses)
FROM EMPLOYEE
FROM CONDITION
ELSE
RESULT.permission := 'REVOKED';
END IF;
END
$do$;
SELECT * FROM RESULT
You can update the result table with join also, while insert i changed the query a little bit.
--insertintoresult
INSERT INTO RESULT (empId, username, userrole, roles,permission)
SELECT empId, e.username, e.userrole, roles,
c.permissions
FROM EMPLOYEE e,CONDITION c where e.roles=c.userrole and e.accesses= c.accesses order by empId;
SELECT * FROM RESULT;
INSERT INTO EMPLOYEE VALUES
(0004, 'Dave new','sales rep', 'admin','privileged');
INSERT INTO EMPLOYEE VALUES
(0005, 'Ava new','finance manager', 'Managerial role','not privileged');
INSERT INTO RESULT (empId, username, userrole, roles)
SELECT empId, username, userrole, roles
FROM EMPLOYEE ON CONFLICT (empId) DO NOTHING;
UPDATE
RESULT p
SET
permission = c.permissions
FROM
EMPLOYEE e,CONDITION c
WHERE
e.roles=c.userrole and e.accesses= c.accesses and p.empId=e.empid;
SELECT * FROM RESULT order by empid;

Flyway migration in postgresql?

I'm trying to add an entry to Postgresql using such a request
insert into customer (id, email, name, number_telephone) VALUES (public.hibernate_sequence_customer.nextval, 'abc#jar.ru' , 'Henry', '89132547898');
, but flyway throws an error
Error: table "hibernate_sequence_customer" is missing in the FROM clause
In the project structure
enter image description here
The next value of your sequence is accessed via nextval('public.hibernate_sequence_customer'), not dot notation.
insert into customer (
id,
email,
name,
number_telephone)
VALUES (
nextval('public.hibernate_sequence_customer'),
'abc#jar.ru' ,
'Henry',
'89132547898');
but if you define id column as serial, you don't need to call the sequence at all.
create table customer (
id serial primary key,
email text,
name text,
number_telephone text);
Just skip it in your insert:
insert into customer (
email,
name,
number_telephone)
VALUES (
'abc#jar.ru' ,
'Henry',
'89132547898');
If you later need to refer to the sequence responsible for the id column - to get its current value, for example - you can use currval(pg_get_serial_sequence('customer','id')).

Create new entries for a particular account_id in the same using postgres

I have a table called account(id,account_id,name,status). Already data is present for these columns say:
Table account:
I have to first query the account_id with the name as xyz and create new entries for that account_id with name as kjf and lmn and status as fail.
The new table will look like as below after insert
Can someone help me for writing a query for this? I had tried :
INSERT INTO account (id, account_id, name, status,)
SELECT uuid_generate_v4(), account_id, 'kjh', 'fail' FROM account;
This shows error as account_is is unique.
With SQL, you can try this:
with
v1 as (select max(id)+1 as maxid from account),
v2 as (select account_id as newid from account where name='xyz')
insert into account
select (select maxid from v1), (select newid from v2), 'kjh', 'fail';

Select rows conditionally and insert into another table conditionally

How to insert into table 2 all field values of a row from table A, where all values in a column A in table 1 that satisfy a condition on column B of table 1 ,but do not exist in table 2.How to frame a query using not exists?
I tried this:
INSERT INTO Teachermast (
teacher_code,
teacher_name,
designation,
dept_code,
contact_no,
email,
address,
dob,
PASSWORD
)
SELECT
userId,
username,
designation,
dept,
contact_no,
email,
address,
dob,
PASSWORD
FROM
UserMast
WHERE NOT EXISTS
(SELECT
userId
FROM
UserMast
WHERE usertype = '3')
but this doesnt seem to work.
Kindly help.
You could do a MERGE
create table users
(
userId varchar(50),
username varchar(50),
usertype int,
password varchar(50),
contact_no varchar(50),
email varchar(50),
faxno varchar(50),
address varchar(50),
created_date date,
updated_date date,
status varchar(50),
gender varchar(50),
dob date,
lasttimelogin datetime,
login_time datetime,
logoutt_time datetime,
designation varchar(50),
dept varchar(50),
email_pass varchar(50)
)
insert into users values('T0003','Ankita',3,'12345','9858‌​585245','anki#gmail.com','201','l block noid sec 25',NULL,NULL,NULL,'Female','11/09/1990',NULL,NULL,NULL,'Teacher','EC',NULL);
insert into users values('T0004','Ribha',3,'12345','9512365423','sharma#gmail.com',NULL,'221 dwarka sec 10',NULL,NULL,NULL,'Female','12/02/1989',NULL,NULL,NULL,'Teacher','EC',NULL);
create table teachers
(
teacher_code varchar(50),
teacher_name varchar(50),
designation varchar(50),
dept_code varchar(50),
contact_no varchar(50),
email varchar(50),
address varchar(50),
dob date,
password varchar(50)
)
insert into teachers values('T0002','Tanvi','Teacher','CS','9632569856','tan123#gmai‌​l.com','298 mayur vihar ph 1','29/06/1990','12345');
insert into teachers values('T0003','Ankita','Teacher','EC','9858585245','anki#gmail‌​.com','201 l block noida sec 25','11/09/1990','12345');
merge teachers as target
using (select userid, username, designation, dept, contact_no, email, address, dob, password from users where usertype = 3)
as source(userid, username, designation, dept, contact_no, email, address, dob, password)
on target.teacher_code = source.userid
when not matched by target then
insert (teacher_code, teacher_name, designation, dept_code, contact_no, email, address, dob, password)
values (source.userid, source.username, source.designation, source.dept, source.contact_no, source.email, source.address, source.dob, source.password);
select * from teachers
However, I think there are issues with your database design. With your current model, you could have, for example, a different address (or password!) for Ankita in table1 compared to table2. And if you change any of that information you would have to change it in both places.
Could you, for example, just insert everyone into "users" and have "teachers" be a view
select {columns} from users where usertype = 3
Please try this query
SELECT
t.userId,
t.username,
t.designation,
t.dept,
t.contact_no,
t.email,
t.address,
t.dob,
t.PASSWORD
FROM Teachermast as t
LEFT join UserMast as u on t.userId = u.teacher_code
WHERE t.usertype = '3' and u.teacher_code is null

Finding distinct values of non Primary Key column in CQL Cassandra

I use the following code for creating table:
CREATE KEYSPACE mykeyspace
WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };
USE mykeyspace;
CREATE TABLE users (
user_id int PRIMARY KEY,
fname text,
lname text
);
INSERT INTO users (user_id, fname, lname)
VALUES (1745, 'john', 'smith');
INSERT INTO users (user_id, fname, lname)
VALUES (1744, 'john', 'doe');
INSERT INTO users (user_id, fname, lname)
VALUES (1746, 'john', 'smith');
I would like to find the distinct value of lname column (that is not a PRIMARY KEY). I would like to get the following result:
lname
-------
smith
By using SELECT DISTINCT lname FROM users;
However since lname is not a PRIMARY KEY I get the following error:
InvalidRequest: code=2200 [Invalid query] message="SELECT DISTINCT queries must
only request partition key columns and/or static columns (not lname)"
cqlsh:mykeyspace> SELECT DISTINCT lname FROM users;
How can I get the distinct values from lname?
User - Undefined_variable - makes two good points:
In Cassandra, you need to build your data model to match your query patterns. This sometimes means duplicating your data into additional tables, to attain the desired level of query flexibility.
DISTINCT only works on partition keys.
So, one way to get this to work, would be to build a specific table to support that query:
CREATE TABLE users_by_lname (
lname text,
fname text,
user_id int,
PRIMARY KEY (lname, fname, user_id)
);
Now after I run your INSERTs to this new query table, this works:
aploetz#cqlsh:stackoverflow> SELECT DISTINCT lname FROm users_by_lname ;
lname
-------
smith
doe
(2 rows)
Notes: In this table, all rows with the same partition key (lname) will be sorted by fname, as fname is a clustering key. I added user_id as an additional clustering key, just to ensure uniqueness.
There is no such functionality in cassandra. DISTINCT is possible on partition key only.
You should Design Your data model based on your requirements.
You have to process the data in application logic (spark may be useful)