Postgresql GROUB BY combination - postgresql

Hi I have a problem with the group by clause if I have combinations between,
This is a part from my table with combinations:
CREATE TABLE sampleTable
(
id serial primary key,
sat1 varchar(3),
sat2 varchar(3)
);
INSERT INTO sampleTable
(sat1, sat2)
VALUES
('LE7','LE7'),
('LE8','LE7'),
('LE7','LE7'),
('LE7','LC8'),
('LE7','LE8'),
('LE8','LE7'),
...
http://sqlfiddle.com/#!15/63104/2
I search the count of combinations, but for me the combination sat1,sat2 is the same like sat2,sat1.
My (wrong) SQL-Code:
select sat1, sat2, count(*) from sampleTable group by sat1, sat2 order by sat1
and the result:
sat1 sat2 count
1 LC8 LC8 27
2 LC8 LE7 17
3 LE7 LE7 200
4 LE7 LC8 22
5 LM1 LM2 2
6 LM1 LM1 12
7 LM2 LM2 6
8 LM2 LM1 3
but it should by:
sat1 sat2 count
1 LC8 LC8 27
2 LC8 LE7 39 (17+22 / line 2 & 4)
3 LE7 LE7 200
4 LM1 LM2 5 (2+3 / line 5 & 8)
5 LM1 LM1 12
6 LM2 LM2 6
Has anyone a SQL-Code which solved my question?
Thanks for Help!!

Use LEAST() and GREATEST() to "simplify" the 2 grouping columns:
Query 1:
select least(sat1, sat2), greatest(sat1, sat2), count(*)
from sampleTable
group by least(sat1, sat2), greatest(sat1, sat2)
order by least(sat1, sat2)
[Results][2]:
| least | greatest | count |
|-------|----------|-------|
| LC8 | LC8 | 27 |
| LC8 | LE7 | 39 |
| LE7 | LE7 | 200 |
| LM1 | LM1 | 12 |
| LM1 | LM2 | 5 |
| LM2 | LM2 | 6 |
See this SQL Fiddle

Related

Postgres: How to delete rows from auto-generated tables? [duplicate]

This question already has answers here:
PostgreSQL "Column does not exist" but it actually does
(6 answers)
sql statement error: "column .. does not exist"
(1 answer)
Closed 10 months ago.
In postgres, I have generated table user and table organizations. There is some relationship between them, i.e.: multiple users belong to one organization.
The table user_organizations_organization was auto-generated by postgres.
Here I have:
development=# select * from user_organizations_organization;
userId | organizationId
--------+----------------
1 | 1
2 | 1
3 | 2
4 | 2
5 | 1
6 | 1
7 | 2
8 | 2
9 | 3
10 | 3
11 | 4
12 | 4
13 | 3
14 | 3
15 | 4
16 | 4
17 | 5
18 | 5
19 | 6
20 | 6
21 | 5
22 | 5
23 | 6
24 | 6
25 | 7
26 | 7
27 | 8
28 | 8
29 | 7
30 | 7
31 | 8
32 | 8
33 | 9
34 | 9
35 | 10
36 | 10
37 | 9
38 | 9
39 | 10
40 | 10
(40 rows)
I want to delete relationships related to organizations 5,6,7,8:
development=# delete from user_organizations_organization where organizationId in (5,6,7,8);
ERROR: column "organizationid" does not exist
LINE 1: delete from user_organizations_organization where organizati...
^
HINT: Perhaps you meant to reference the column "user_organizations_organization.organizationId".
development=#
How can I delete them?

How to GROUP BY hour and take missing hours as 0 in POSTGRESQL

I am making GROUP BY hour for one day. In this case there are some time intervals with no data. How can i take these missing hours as 0 value?. Then there would be always 23 value in my query result.
Below what I tried so far.
SELECT COUNT(*), extract(hour from created_date) as hourr
FROM client_requests
WHERE created_date > '2020-02-24 00:00:00' and created_date < '2020-02-24 23:59:59'
GROUP BY extract(hour from created_date)
ORDER BY extract(hour from created_date) ASC
result is like below:
count | hourr |
------------------------------------
1 | 0
1 | 6
5 | 8
14 | 9
35 | 10
37 | 11
40 | 12
32 | 13
18 | 14
28 | 15
39 | 16
31 | 17
30 | 18
16 | 19
7 | 20
11 | 21
14 | 22
But i need like this
count | hourr |
------------------------------------
1 | 0
0 | 1
0 | 2
0 | 3
0 | 4
0 | 5
1 | 6
0 | 7
5 | 8
14 | 9
35 | 10
37 | 11
40 | 12
32 | 13
18 | 14
28 | 15
39 | 16
31 | 17
30 | 18
16 | 19
7 | 20
11 | 21
14 | 22
0 | 23
Left join with a generated table of hours:
SELECT coalesce(count(r.*), 0) AS count,
h.h as hour
FROM generate_series(0, 23) AS h
LEFT JOIN client_requests AS r
ON extract(hour from r.created_date) = h.h
AND r.created_date >= '2020-02-24 00:00:00'
AND r.created_date < '2020-02-25 00:00:00'
GROUP BY h.h
ORDER BY h.h;

postgresql select multiple values

I have two tables:
Table1 'jobs'
num | job1 | job2
--------------------
1 | 14 | 12
2 | 23 | 15
3 | 3 | 12
4 | 21 | 3
5 | 6 | 8
Table2 'users'
id | name
------------
3 | name1
6 | name2
12 | name3
14 | name4
15 | name5
I need to have query which shows:
num | job1 | job2
--------------------------
1 | name4 | name3
2 | name6 | name5
Thanks already
SELECT j.num, u1.name, u2.name
FROM jobs j, users u1, users u2
WHERE j.job1 = u1.id
AND j.job2 = u2.id

Select rows by one column value should only be repeat N times

My table is:
id sub_id datetime resource
---|-----|------------|-------
1 | 10 | 04/03/2009 | 399
2 | 11 | 04/03/2009 | 244
3 | 10 | 04/03/2009 | 555
4 | 10 | 03/03/2009 | 300
5 | 11 | 03/03/2009 | 200
6 | 11 | 03/03/2009 | 500
7 | 11 | 24/12/2008 | 600
8 | 13 | 01/01/2009 | 750
9 | 10 | 01/01/2009 | 760
10 | 13 | 01/01/2009 | 570
11 | 11 | 01/01/2009 | 870
12 | 13 | 01/01/2009 | 670
13 | 13 | 01/01/2009 | 703
14 | 13 | 01/01/2009 | 705
I need to select for each sub_id only 2 times
Result would be:
id sub_id datetime resource
---|-----|------------|-------
1 | 10 | 04/03/2009 | 399
3 | 10 | 04/03/2009 | 555
5 | 11 | 03/03/2009 | 200
6 | 11 | 03/03/2009 | 500
8 | 13 | 01/01/2009 | 750
10 | 13 | 01/01/2009 | 570
How can I achieve this result in postgres ?
Use the window function row_number():
select id, sub_id, datetime, resource
from (
select *, row_number() over (partition by sub_id order by id)
from my_table
) s
where row_number < 3;
look at the order column (I use id to match your sample):
t=# with data as (select *,count(1) over (partition by sub_id order by id) from t)
select id,sub_id,datetime,resource from data where count <3;
id | sub_id | datetime | resource
----+--------+------------+----------
1 | 10 | 2009-03-04 | 399
3 | 10 | 2009-03-04 | 555
2 | 11 | 2009-03-04 | 244
5 | 11 | 2009-03-03 | 200
8 | 13 | 2009-01-01 | 750
10 | 13 | 2009-01-01 | 570
(6 rows)

Get column a and column b through first parameter to last parameter

I'm newbie on tsql and stuck on this problem. Can anyone help this prb?
I have a table like below; (use SQL 2008 Express Edt.)
ID COL1 COL2
1 7 2
2 7 3
3 7 4
4 7 5
5 9 2
6 9 3
7 9 4
8 9 5
9 11 2
10 11 3
11 11 4
12 11 5
how to use select query to fetch between 7/3 and 11/2 (both columns and first/last rows included)
SQL Fiddle
MS SQL Server 2008 Schema Setup:
create table YourTable
(
ID int,
COL1 int,
COL2 int
)
insert into YourTable values
(1 ,7 ,2),
(2 ,7 ,3),
(3 ,7 ,4),
(4 ,7 ,5),
(5 ,9 ,2),
(6 ,9 ,3),
(7 ,9 ,4),
(8 ,9 ,5),
(9 ,11 ,2),
(10 ,11 ,3),
(11 ,11 ,4),
(12 ,11 ,5)
Query 1:
select *
from YourTable
where (COL1 > 7 and COL1 < 11) or
(COL1 = 7 and COL2 >= 3) or
(COL1 = 11 and COL2 <= 2)
Results:
| ID | COL1 | COL2 |
--------------------
| 2 | 7 | 3 |
| 3 | 7 | 4 |
| 4 | 7 | 5 |
| 5 | 9 | 2 |
| 6 | 9 | 3 |
| 7 | 9 | 4 |
| 8 | 9 | 5 |
| 9 | 11 | 2 |