How to aggregate all numbers of a column in postgresql? - postgresql

I'm trying to find some of all rows, with the same city name in an specific time. My table is :
CREATE TABLE fp_stores_data_test (
time INTEGER,
city VARCHAR(20),
market_id INTEGER,
product_id INTEGER,
price INTEGER,
has_sold INTEGER,
PRIMARY KEY (time, city, province, market_id ,product_id)
);
I want to create another table which is have time,city and has_sold columns. This one will show how much is sold in this city on that specific time. I don't know how to create this table using my first table. some sample input:
1594809782,city1,0,3588,54000,36
1594809782,city1,0,4813,59000,16
1594809782,city2,0,879,35000,33
1594809782,city2,0,2902,57000,13
1594809786,city1,0,3199,52000,5
1594809786,city1,1,864,35000,32
1594809786,city2,1,5297,37000,14
1594809786,city2,1,5339,40000,19
here, for city1 in time 1594809782 we have two rows. These two row will be one row in the next table. with the same time and city but has_sold values will sum up in.
1594809782,city1,52
1594809782,city2,46
1594809786,city1,37
1594809786,city2,33

I think that this will do exactly what you need:
select time, city, sum(has_sold) has_sold
from fp_stores_data_test
group by time, city
order by time, city;
And you can store the query results in a table like this
select time, city, sum(has_sold) has_sold
into [temporary table] fp_stores_data_agg
from fp_stores_data_test
group by time, city;
[temporary table] is of course optional if you only need the aggregated table during the session and remove it afterwards.

Related

Optional filter on a column of an outer joined table in the where clause

I have got two tables:
create table student
(
studentid bigint primary key not null,
name varchar(200) not null
);
create table courseregistration
(
studentid bigint not null,
coursenamename varchar(200) not null,
isfinished boolean default false
);
--insert some data
insert into student values(1,'Dave');
insert into courseregistration values(1,'SQL',true);
Student is fetched with id, so it should be always returned in the result. Entry in the courseregistration is optional and should be returned if there are matching rows and those matching rows should be filtered on isfinished=false. This means I want to get the course regsitrations that are not finished yet. Tried to outer join student with courseregistration and filter courseregistration on isfinished=false. Note that, I still want to retrieve the student.
Trying this returns no rows:
select * from student
left outer join courseregistration using(studentid)
where studentid = 1
and courseregistration.isfinished = false
What I'd want in the example above, is a result set with 1 row student, but course rows null (because the only example has the isfinished=true). One more constraint though. If there is no corresponding row in courseregistration, there should still be a result for the student entry.
This is an adjusted example. I can tweak my code to solve the problem, but I really wonder, what is the "correct/smart way" of solving this in postgresql?
PS I have used the (+) in Oracle previously to solve similar issues.
Isn't this what you are looking for :
select * from student s
left outer join courseregistration cr
on s.studentid = cr.studentid
and cr.isfinished = false
where s.studentid = 1
db<>fiddle here

How to create date range as From date to To date from given dates excluding weekends

I have a table PTO:
DECLARE #PTO TABLE
(
employee_id VARCHAR(50),
pto_type VARCHAR(10),
date VARCHAR(20)
)
INSERT INTO #PTO
VALUES ('12XY34', 'VACATION', '4/04/2019'),
('12XY34', 'VACATION', '4/05/2019'),
('12XY34', 'VACATION', '4/08/2019'),
('98XX99', 'SICK', '4/04/2019'),
('98XX99', 'SICK', '4/05/2019'),
(‘12XY34’, ‘VACATION’, ‘4/10/2019’),
(‘12XY34’, ‘VACATION’, ‘4/11/2019’)
I want result as below:
employee_id pto_type from_date to_date
--------------------------------------------
12XY34 VACATION 4/04/2019 4/08/2019
98XX99 SICK 4/04/2019 4/05/2019
12XY34 VACATION 4/10/2019 4/11/2019
Select employee. Ptotype, min(date) from, max(date) to
From PTO
Group by employee, ptotype
That is what you asked but what if person has multiple vacations? Does data still look like this?

Insert into table from select distinct query in postgresql

I have a table with 33 columns that has several duplicates so i am trying to remove all the duplicates this way because this select distinct query has the correct number of data.
CREATE TABLE students (
school char(2),sex char(1),age int,address char(1),famsize char(3),
Pstatus char(1),Medu int,Fedu int,Mjob varchar,Fjob varchar,reason varchar,
guardian varchar,traveltime int,studytime int,failures char(1),
schoolsup varchar,famsup varchar,paid varchar,activities varchar,
nursery varchar,higher varchar,internet varchar,romantic varchar,
famrel int,freetime int,goout int,Dalc int,Walc int,
health int,absences int,id serial primary key)
I want to insert all values from this select distinct query
with 8 columns into a different empty table.
SELECT DISTINCT ("school","sex","age","address","famsize","Pstatus","Medu","Fedu","Mjob","Fjob","reason","nursery","internet")
FROM students;
I want to insert all values from this select distinct query with 8 columns into a different empty table.
Use create table .. as select ... if you want to create the table
create table new_table
as
SELECT DISTINCT school, sex, age, address, famsize, "Pstatus", "Medu", "Fedu", "Mjob", "Fjob", reason, nursery, internet
FROM students;
Other wise just use an insert based on a select:
insert into empty_table (school, sex, age, address, famsize, "Pstatus", "Medu", "Fedu", "Mjob", "Fjob", reason, nursery, internet)
SELECT DISTINCT school, sex, age, address, famsize, "Pstatus", "Medu", "Fedu", "Mjob", "Fjob", reason, nursery, internet
FROM students;
Very important: do not put parentheses around the columns in the select list - that creates a single column with an anonymous record type.
insert into destinationTable(dC1, dC2, dC3, dC4, dC5, dC6, dC7, dC8)
select sC1, sC2, sC3, sC4, sC5, sC6, sC7, sC8
from sourceTable
You can join the tables to get the 33 columns.

adding to table a column with serial numbers that based on information in two columns

I have a 100 rows table ("GendersHeight") with two columns: the 1st column ("gender") is a string ("male" or "female"). the 2nd column ("height") is a variable number. I sorted the table based on these two columns accordingly:
select *
into MyNewTable
from GendersHeight
order by gender, height DESC
(there are 40 "male" rows, and 60 "female" rows in my table)
Now I'd like to add a new column (3rd column) to table "MyNewTable" that holds a serial number.
If I'll use the script:
ALTER TABLE MyNewTable
Add column MySorter serial NOT NULL;
I'll just get a serial column that ranges from 1 to 100.
BUT - what I want really to achieve here is creating a column that would range from 1 to 60 first, for all the "female" entries, and then would range from 1 to 40 for all the "male" entries.
Is there a way to create such a serial column that is taking in account the nature of the "gender" column?
You can use the rank() function:
CREATE TABLE "MyNewTable" AS
SELECT gender,
height,
rank() OVER(partition by gender order by height) as myrank
FROM "GendersHeight"

Postgresql. select SUM value from arrays

Condition:
There are two tables with arrays.
Note food.integer and price.food_id specified array.
CREATE TABLE food (
id integer[] NOT NULL,
name character varying(255),
);
INSERT INTO food VALUES ('{1}', 'Apple');
INSERT INTO food VALUES ('{1,1}', 'Orange');
INSERT INTO food VALUES ('{1,2}', 'banana');
and
CREATE TABLE price (
id bigint NOT NULL,
food_id integer[],
value double precision DEFAULT 0
);
INSERT INTO price VALUES (44, '{1}', 500);
INSERT INTO price VALUES (55, '{1,1}', 100);
INSERT INTO price VALUES (66, '{1,2}', 200);
Need to get the sum value of all the products from table food.
Please help make a sql query.
ANSWER:
{1} - Apple - 800 (500+100+200)
What about this:
select
name,
sum(value)
from
(select unnest(id) as food_id, name from food) food_cte
join (select distinct id, unnest(food_id) as food_id, value from price) price_cte using (food_id)
group by
name
It is difficult to understand your question, but this query at least returns 800 for Apple.
try the following command,
SELECT F.ID,F.NAME,SUM(P.VALUE) FROM FOOD F,PRICE P WHERE F.ID=P.FOOT_ID;