Postgresql count different groups in one query - postgresql

I need to calculate the counts per city,state and country. For example if i have the following data in my table T1:
name city state country
------------------------------
name1 c1 s1 C1
name2 c1 s1 C1
name3 c2 s1 C1
name4 c3 s1 C1
name5 c4 s2 C1
name6 c5 s2 C1
name7 c5 s3 C1
name8 c12 s12 C2
the query should results in:
city state country citycount, statecount, countrycount
-------------------------------------------------------------------
c1 s1 C1 2 4 7
c2 s1 C1 1 4 7
c3 s1 C1 1 4 7
c4 s2 C1 1 2 7
c5 s2 C1 1 2 7
c5 s3 C1 1 1 7
c12 s12 C2 1 1 1
if i do group by and count then i need to write 3 different queries. But i want to do it in one query. please help.

You can use window functions, for example one solution could be this one:
SELECT DISTINCT city
,STATE
,country
,count(*) OVER (PARTITION BY city,STATE,country) AS citycount
,count(*) OVER (PARTITION BY STATE,country) AS statecount
,count(*) OVER (PARTITION BY country) AS countrycount
FROM T1
ORDER BY city
,STATE
,country
Please see a fiddle here.

Related

spark scala - How to create a UDT (cassandra user data type [list <UDT>]) from a CSV file

I have a CSV file with ID, ID1, ID2, col1, col2, and col3 fields...I need to group the record based on the ID field and convert it to a UDT list.
ex:
ID ID1 ID2 COL1 COL2 COL3 COL4
1 AA 01 A B C D
1 AA 02 A B C D
1 AA 02 B C D E
1 AA 03 A B C D
2 BB 01 A B C D
2 BB 02 A B C D
3 CC 01 A B C D
3 CC 01 B C D E
THE OUTPUT SHOULD BE
1,[{ID1:"AA",ID2:"01"},{ID1:"AA",ID2:"02"},{ID1:"AA",ID2:"03"}]
2,[{ID1:"BB",ID2:"01"},{ID1:"BB",ID2:"02"}]
3,[{ID1:"CC",ID2:"01"}] (grouped by ID; rest of the ID fields in a list array)
I tried collect_list / collect_set to group the fields but could not convert them to an array.

how to move data from one column to another column's row in postgres?

How I start coding to get below output.
id
Column1
1
A1
2
A2
3
A1
4
A2
5
A1
6
A1
output should be below.
id
Column1
Column1.1
Column1.2
1
A1
A1
2
A2
A2
3
A1
A1
4
A2
A2
5
A1
A1
6
A1
A1
We can try to use CASE WHEN expression to make it.
SELECT id,
Column1,
CASE WHEN Column1 = 'A1' THEN Column1 END 'Column1.1',
CASE WHEN Column1 = 'A2' THEN Column1 END 'Column1.2'
FROM T

KDB get substring

How can I add a column containing a substring of a another columns containing symbols. So, go from
t:flip `date`sym`pos!(`d1`d1`d1`d2;`aaaA1`bbbA1`aaaA2`aaaA3;1 2 3 1)
date sym pos
d1 aaaA1 1
d1 bbA1 2
d1 aaaA2 3
d2 aaaA3 1
to
t:flip `date`sym`pos`ext!(`d1`d1`d1`d2;`aaaA1`bbbA1`aaaA2`aaaA3;1 2 3 1;`aaa`bbb`aaa`aaa)
date sym pos ext
d1 aaaA1 1 aaa
d1 bbA1 2 bb
d1 aaaA2 3 aaa
d2 aaaA3 1 aaa
EDIT. The substring should always contain the first len(symbol) -2 characters, so in my example above, aaa for aaaAx and bb for bbAx
If the substring you wish to extract is a constant length, you can do something like this following:
q)t:flip `date`sym`pos!(`d1`d1`d1`d2;`aaaA1`bbbA1`aaaA2`aaaA3;1 2 3 1)
q)update ext:`$3#'string sym from t
date sym pos ext
------------------
d1 aaaA1 1 aaa
d1 bbbA1 2 bbb
d1 aaaA2 3 aaa
d2 aaaA3 1 aaa
If that's not the case, please provide some more detail with regards to how the substring to be extracted can be identified
Hope this helps
Jonathon
There can be a clever way of applying this below, but this is what i first came up with.
t:flip `date`sym`pos!(`d1`d1`d1`d2;`aaaA1`bbbA1`aaaA2`aaaA3;1 2 3 1)
t: update ctr: {-2 + count string x} each sym from t;
t:{[x] :update ext:x[`ctr]#string(x[`sym]) from x} each t;
2nd line is applying your logic of: len(symbol) - 2
3rd line is taking 'ctr' number of characters from the original symbol characters.
You didn’t say so, but this is kdb+, so let’s assume:
your table is long
your sym column has duplicates
You don’t need to convert all the symbols to strings and back: only the distinct ones. (In this example, I’ve changed one of the symbols to create a duplicate.)
q)t:flip `date`sym`pos!(`d1`d1`d1`d2;`aaaA1`bbbA1`aaaA2`aaaA1;1 2 3 1)
q)update ext:{nub:distinct x;(`$-2 _'string nub)nub?x}sym from t
date sym pos ext
------------------
d1 aaaA1 1 aaa
d1 bbbA1 2 bbb
d1 aaaA2 3 aaa
d2 aaaA1 1 aaa
The utility .Q.fu applies a function to the distinct items.
q)update ext:.Q.fu[{`$-2 _'string x};sym] from t
date sym pos ext
------------------
d1 aaaA1 1 aaa
d1 bbbA1 2 bbb
d1 aaaA2 3 aaa
d2 aaaA1 1 aaa
This operation would be faster if the sym column were already stored as an enumeration, because the distinct values would then be available without calculation.
Using drop:
q)t:flip `date`sym`pos!(`d1`d1`d1`d2;`aaaA1`bbA1`aaaA2`aaaA3;1 2 3 1)
q)update ext:`$-2_'string sym from t
date sym pos ext
------------------
d1 aaaA1 1 aaa
d1 bbA1 2 bb
d1 aaaA2 3 aaa
d2 aaaA3 1 aaa

Give "ID" to multiple columns

Is there a native postgresql function that gives "IDs", based on the column.
column 1 column 2 id1 id2
aa AA 1 1
aa BB 1 2
bb BB 2 2
cc BB 3 2
cc CC 3 3
dd DD 4 4
I only want the "ID" to increment, when the value in the column changes. Otherwise, the "ID" should be the same.
SELECT o.column1, o.column2
, dense_rank() OVER (ORDER BY column1) AS id1
, dense_rank() OVER (ORDER BY column2) AS id2
FROM ordi o
;

DB2 using if condition

My table contain below records.. Table Name : Cus1
Column: c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15
Records: 1 2 2 3 4 4 5 6 6 6 7 7 8 8 9 -1st record
1 2 3 3 3 4 4 5 5 5 5 6 7 7 8 -2nd record
How to get result like below using above table:
Column: c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15
Records: 1 2 3 4 5 6 7 8 9 NULL NULL NULL NULL NULL NULL -1st record
1 2 3 4 5 6 7 8 NULL NULL NULL NULL NULL NULL NULL -2nd record
its possible in DB2 using if condition ?
No idea what is meant by "using if condition", but perhaps the following may be of interest?
Setup:
create table cus1
( c1 dec(3), c2 dec(3), c3 dec(3), c4 dec(3), c5 dec(3)
, c6 dec(3), c7 dec(3), c8 dec(3), c9 dec(3), c10 dec(3)
, c11 dec(3), c12 dec(3), c13 dec(3), c14 dec(3), c15 dec(3)
)
;
insert into cus1 values
( 1, 2, 2, 3, 4, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9)
, ( 1, 2, 3, 3, 3, 4, 4, 5, 5, 5, 5, 6, 7, 7, 8)
;
Use table data from setup to generate queries; each created here as a VIEW to be queried for the final result:
create view cus1_unpivot_view as
with
cus1_rn as
( select row_number() over() as rn
, a.*
from cus1 a
)
SELECT rn, cn, cn_val
FROM cus1_rn as C
, lateral
( values ( 1, C.c1 ), ( 6, C.c6 ), ( 11, C.c11 )
, ( 2, C.c2 ), ( 7, C.c7 ), ( 12, C.c12 )
, ( 3, C.c3 ), ( 8, C.c8 ), ( 13, C.c13 )
, ( 4, C.c4 ), ( 9, C.c9 ), ( 14, C.c14 )
, ( 5, C.c5 ), ( 10, C.c10 ), ( 15, C.c15 )
) AS X( cn, cn_val )
; /* create an unpivot view of columns to rows */
create view cus1_unmatched as
select a.rn, a.cn, b.cn_val
from cus1_unpivot_view as a
left join
( select distinct rn, cn_val
from cus1_unpivot_view as d
) as b
on a.rn=b.rn
and a.cn=b.cn_val
; /* Generate unmatched values to get NULL results */
create view cus1_pivot as
select rn
, max( case when cn=1 then cn_val end ) as c1
, max( case when cn=2 then cn_val end ) as c2
, max( case when cn=3 then cn_val end ) as c3
, max( case when cn=4 then cn_val end ) as c4
, max( case when cn=5 then cn_val end ) as c5
, max( case when cn=6 then cn_val end ) as c6
, max( case when cn=7 then cn_val end ) as c7
, max( case when cn=8 then cn_val end ) as c8
, max( case when cn=9 then cn_val end ) as c9
, max( case when cn=10 then cn_val end ) as c10
, max( case when cn=11 then cn_val end ) as c11
, max( case when cn=12 then cn_val end ) as c12
, max( case when cn=13 then cn_val end ) as c13
, max( case when cn=14 then cn_val end ) as c14
, max( case when cn=15 then cn_val end ) as c15
from cus1_unmatched
group by rn
; /* pivot row data back to columns with the NULLs */
Finally, query that last VIEW to omit the row-numbering and present the data; compare the results to the desired output:
select
c1 , c2 , c3 , c4 , c5
, c6 , c7 , c8 , c9 , c10
, c11 , c12 , c13 , c14 , c15
from cus1_pivot
order by rn
; -- the following is a likeness of a report from the above query:
....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8....+...
C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15
1 2 3 4 5 6 7 8 9 - - - - - -
1 2 3 4 5 6 7 8 - - - - - - -
******** End of data ********