Create insert query from select query by incrementing id - postgresql

I am trying to copy data from a table and insert into it with some different fields. Here while inserting it results in a problem where I have to specify id(primary key) which is supposed to be auto incrementing but for some reason not set to serial when the tables were created. I wish to add an incrementing id in the data to be inserted based on the already existing data.
Any help will be appreciated.
WITH my_admin_id AS
(
SELECT id
FROM dashboard_admin
WHERE email = 'someone#somedomain.com'
),
get_admin AS
(
SELECT id
FROM dashboard_admin
WHERE user_id IN (SELECT id FROM auth_user WHERE username = 'demo')
),
get_admin_projects AS
(
SELECT *
FROM dashboard_project
WHERE admin_id IN (SELECT * FROM get_admin LIMIT 1)
AND is_deleted = 'false'
) INSERT INTO dashboard_project
(
SELECT id,
name,
created_date,
(SELECT * FROM my_admin_id LIMIT 1)AS admin_id,
category_id,
subcategory_id,
is_deleted FROM get_admin_projects
)
Update :
Earlier the execution of select query meant to be inserted, fetched the following result.
67 1stAd 2017-04-21 15:25:16.430889 100 18 47 false
71 2stAd 2017-05-12 10:18:55.383967 100 34 90 false
Here I have just added a query to get the max id. I just need to increment it for every record in my final select query.
WITH my_admin_id AS
(
SELECT id
FROM dashboard_admin
WHERE email = 'someone#somedomain.com'
),
get_admin AS
(
SELECT id
FROM dashboard_admin
WHERE user_id IN (SELECT id FROM auth_user WHERE username = 'demo')
),
get_max_project AS
(
SELECT MAX(id) FROM dashboard_project
),
get_admin_projects AS
(
SELECT id,
name,
created_date,
admin_id,
category_id,
subcategory_id,
is_deleted
FROM dashboard_project
WHERE admin_id IN (SELECT * FROM get_admin LIMIT 1)
AND is_deleted = 'false'
) (SELECT (SELECT * FROM get_max_project) id,
name,
created_date,
(SELECT * FROM my_admin_id LIMIT 1) AS admin_id,
category_id,
subcategory_id,
is_deleted
FROM get_admin_projects)
This is the resultant value on executing the select query.
101 1stAd 2017-04-21 15:25:16.430889 100 18 47 false
101 2ndAd 2017-05-12 10:18:55.383967 100 34 90 false

Finally got it working like this used the row_number() window function which I added to max id , to increment values above max id.
WITH my_admin_id AS
(
SELECT id
FROM dashboard_admin
WHERE email = 'someone#somedomain.com'
),
get_admin AS
(
SELECT id
FROM dashboard_admin
WHERE user_id IN (SELECT id FROM auth_user WHERE username = 'demo')
),
get_max_project AS
(
SELECT MAX(id) FROM dashboard_project
),
get_admin_projects AS
(
SELECT id,
name,
created_date,
admin_id,
category_id,
subcategory_id,
is_deleted
FROM dashboard_project
WHERE admin_id IN (SELECT * FROM get_admin LIMIT 1)
AND is_deleted = 'false'
)
insert into dashboard_project (SELECT ((SELECT * FROM get_max_project) + row_number() over ()) as id,
name,
created_date,
(SELECT * FROM my_admin_id LIMIT 1) AS admin_id,
category_id,
subcategory_id,
is_deleted
FROM get_admin_projects)

Related

If the object we made by the group is null, I want to give [ ] instead postgresql

with
zakaz as (
select
o.*,
(select f_name from clients where id = o.client_id) as f_name,
(select l_name from clients where id = o.client_id) as l_name,
(select phone from clients where id = o.client_id) as phone,
(select name from item_types where id = o.item_type_id) as item_name,
(select name from trailer_types where id = o.trailer_type_id) as trailer_name,
(select name from cover_types where id = o.cover_type_id) as cover_name,
(select name from cities where id = o.from_city_id) as from_city,
(select name from cities where id = o.to_city_id) as to_city,
(select name from transport_types where id = o.transport_type_id) as transport_type,
(select first_name || ' ' || last_name || ' ' || middle_name as name from workers where id = o.logist_id) as logist_name
from orders as o
where o.transport_type_id = (select id from transport_types where name = $tt$${transport_type}$tt$)
${ where_key ? `and ${where_key} = $v$${where_val}$v$` : ``}
order by o.created_at
),
zakaz_j_agg as (
select
COALESCE(json_agg(zakaz.*), '[]') as array
from zakaz
group by zakaz.status
)
select
json_agg(ord.*) as result
from zakaz_j_agg as ord
Replace json_agg(ord.*) as result with coalesce(json_agg(ord.*), '[]') as result. The same pattern is used in the zakaz_j_agg CTE.
with
zakaz as (... your CTE query ...),
zakaz_j_agg as (... your CTE query ...)
select
coalesce(json_agg(ord.*), '[]') as result
from zakaz_j_agg as ord;

Using WITH clause and INSERT statement in POSTGRESQL

There was a question asked several years ago with a similar title (Using WITH clause with INSERT statement in POSTGRESQL), but I need to figure out a more complicated situation.
I've used the example from POSTGRESQL for using a "With" statement (https://www.postgresql.org/docs/current/queries-with.html). Let's say I made a pre-computed table and wanted to insert the output from the query into it (top_region, total_sales, product_units, and product_sales), how would I do that?
Precomputed table
INSERT INTO top (top_region, total_sales, product_units, product_sales)
select top_region, total_sales, product_units, product_sales
from #not sure here
WITH regional_sales AS (
SELECT region, SUM(amount) AS total_sales
FROM orders
GROUP BY region
), top_regions AS (
SELECT region
FROM regional_sales
WHERE total_sales > (SELECT SUM(total_sales)/10 FROM regional_sales)
)
SELECT region,
product,
SUM(quantity) AS product_units,
SUM(amount) AS product_sales
FROM orders
WHERE region IN (SELECT region FROM top_regions)
GROUP BY region, product;
My query
WITH sales_data AS (
SELECT s.customer_id, s.product_id, s.quantity, pr.list_price, pr.category_id, c.state_id
FROM order_products s
INNER JOIN Products pr ON (s.product_id = pr.product_id)
INNER JOIN Customer c ON (s.customer_id = c.customer_id)
),
t_20cat AS (
SELECT category_id, ROW_NUMBER() OVER (ORDER BY SUM(list_price*quantity) DESC) AS "rank", SUM(list_price*quantity) AS total_sales FROM sales_data
GROUP BY category_id ORDER BY total_sales DESC LIMIT 20
),
t_20cust AS (
SELECT customer_id, ROW_NUMBER() OVER (ORDER BY SUM(list_price*quantity) DESC) AS "rank", SUM(list_price*quantity) AS total_sales FROM sales_data
GROUP BY customer_id ORDER BY total_sales DESC LIMIT 20
),
t_20cc AS (
SELECT customer_id, t_20cust.rank as customer_rank, category_id, t_20cat.rank as category_rank FROM t_20cat, t_20cust
)
SELECT t_20cc.*, COALESCE(SUM(sales_data.quantity), 0) AS quantity_sold, COALESCE(SUM(sales_data.list_price*sales_data.quantity), 0) AS dollar_value
FROM t_20cc
LEFT JOIN sales_data ON (
t_20cc.customer_id = sales_data.customer_id AND t_20cc.category_id = sales_data.category_id
)
GROUP BY t_20cc.customer_id, t_20cc.customer_rank, t_20cc.category_id, t_20cc.category_rank
INSERT INTO top_20(customer_id, customer_rank, category_id, category_rank
select category_id, category_rank, category_id, category_rank
from t_20cc
)
Move the other SELECT query into its own CTE (region_summary), then reference that in the INSERT statement's SELECT ... FROM clause:
WITH regional_sales AS (
SELECT
region,
SUM(amount) AS total_sales
FROM
orders
GROUP BY
region
),
top_regions AS (
SELECT
region
FROM
regional_sales
WHERE
total_sales > ( SELECT SUM( total_sales ) / 10 FROM regional_sales )
),
region_summary AS (
SELECT
region,
product,
SUM(quantity) AS product_units,
SUM(amount) AS product_sales
FROM
orders
WHERE
region IN ( SELECT region FROM top_regions )
GROUP BY
region,
product
)
INSERT INTO top ( top_region, total_sales, product_units, product_sales )
SELECT
region AS top_region,
product AS total_sales,
product_units,
product_sales
FROM
region_summary;

postgres how to insert values with 2 selects

I'm trying to do a query on Postgres but it's not working. I'd like to create an insert query with 2 select:
Example :
INSERT INTO table1 (id_1, id_2)
SELECT id from table_2 where code='01',
SELECT id from table_2 where code='02';
I don't find the good syntax for this.
I believe below query will works for your use case
INSERT INTO stats(totalProduct, totalCustomer, totalOrder)
VALUES(
(SELECT COUNT(*) FROM products),
(SELECT COUNT(*) FROM customers),
(SELECT COUNT(*) FROM orders)
);
you can changes query accordingly
You can add one more SELECT to achieve this
INSERT INTO table_1 (id_1, id_2)
SELECT
(SELECT id FROM table_2 WHERE code = '01') AS Id_1,
(SELECT id FROM table_2 WHERE code = '02') AS Id_2;
Or you may try with CASE expression:
INSERT INTO table1 (id_1, id_2)
SELECT MAX(CASE WHEN code = '01' THEN id ELSE 0 END) AS Id_1,
MAX(CASE WHEN code = '02' THEN id ELSE 0 END) AS Id_2
FROM table_2
Please refer to the working fiddle on db<>fiddle

PostgreSQL - How to count when Distinct On

How to get count of rows for each user_id
select distinct on (user_id) *
from some_table
As in such SQL:
select user_id, count(*)
from some_table
group by user_id
Try this:
SELECT DISTINCT ON (a.user_id)
a.*
FROM
(
SELECT user_id
, count(*) OVER(PARTITION BY user_id)
FROM some_table
) a
If you want to be able to use SELECT * in order to get a "sample row", depending on how large your table is you may be able to use a correlated subquery to get the count of rows for that particular user id:
select distinct on (user_id) *
, (select count (1)
from some_table st2
where st2.user_id = some_table.user_id) as user_row_count
from some_table

Creating a Void Function in PostgreSQL

I am getting an error on this create function code in Postgresql. The error says it is happening around Line 2 at DELETE, but it happens at WITH if I remove that line so I think it is a problem with the format of my Creat Function
create or replace function retention_data(shopId integer) returns void as $$
delete from retention where shop_id = shopId;
WITH ret_grid_step1 as (
select * from (
SELECT
order_id as order_name,
cust_name as cust_name,
email as email,
date(order_date) as created_at,
count(*) as num_items_in_order,
sum(total_price) as sales ,
rank() over (partition BY order_id ORDER BY cust_name ASC) as rnk_shipping_name,
rank() over (partition BY order_id ORDER BY email ASC) as rnk_email
FROM orders
WHERE shop_id = shopId
and order_date is not null and order_date > now()::date - 365 and order_date < now()::date + 1
group by 1,2,3,4
) x
where rnk_shipping_name = 1 and rnk_email = 1
)
insert into retention(shop_id, cust_name, email, last_purchase_dt, total_sales, num_orders, days_since_last_order)
select
shopId as shop_id,
coalesce(b.cust_name,'null') as cust_name,
a.email,
a.last_purchase_dt,
total_sales,
num_orders,
current_date - last_purchase_dt as days_since_last_order
from (
select
email,
max(created_at) as last_purchase_dt,
count(*) as num_orders,
sum(sales) as total_sales
from ret_grid_step1
group by 1
) as a
left join (
select
email,
cust_name,
rank() over (partition BY email ORDER BY created_at DESC) as rnk
from ret_grid_step1
--where cust_name is not null
group by 1,2,created_at
) as b
on a.email = b.email
where b.rnk = 1
and a.email <> '';
$$ language plpgsql;