Example Data
Sql fiddle http://sqlfiddle.com/#!15/c8a17/4
My Query
select
unnest(array[g,g1,g2]) as disp,
unnest(array[g,g||'-'||g1,g||'-'||g1||'-'||g2]) as grp,
unnest(array[1,2,3]) as ord,
unnest(array['assesvalue','lst2','salesvalue','itemprofit','profitper','itemstockvalue'])as analysis,
unnest(array[value1,tt,sv,tp,per,tsv])as val
from (
select
g,
g1,
g2,
sum(value1) as value1,
sum(tt) as tt,
sum(sv) as sv,
sum(tp) as tp,
sum(per) as per,
sum(tsv) as tsv
from table1
group by g,g1,g2
) as ta
It Show the output like this
disp grp ord analysis val
A A 1 assesvalue 100
B A-B 2 lst2 30
C A-B-C 3 salesvalue 20
A A 1 itemprofit 5
B A-B 2 profitper 1
C A-B-C 3 itemstockvalue 10
Expected Result :
disp grp ord analysis val
A A 1 assesvalue 100
A A 1 lst2 30
A A 1 salesvalue 20
A A 1 itemprofit 5
A A 1 profitper 1
A A 1 itemstockvalue 10
B A-B 2 assesvalue 100
B A-B 2 lst2 30
B A-B 2 salesvalue 20
B A-B 2 itemprofit 5
B A-B 2 profitper 1
B A-B 2 itemstockvalue 10
C A-B-C 3 assesvalue 100
C A-B-C 3 lst2 30
C A-B-C 3 salesvalue 20
C A-B-C 3 itemprofit 5
C A-B-C 3 profitper 1
C A-B-C 3 itemstockvalue 10
In Query i am using multiple unnest.
first 3 unnest inside have 3 columns other have 6 columns that its show wrong output but if last 2 unnest have less then 6 its show my expected result.
what am doing wrong in query??
i am using postgresql 9.3
Related
I have a table that looks like this:
id
values
1
a
2
b
3
c
4
d
5
e
6
f
and I need to generate group_id column to be able to collect rows in a batch using
select collect_list(values) from table group by group_id
For example, for batchSize = 2
id
values
group_id
1
a
1
2
b
1
3
c
2
4
d
2
5
e
3
6
f
3
to get it out:
group_id
collect_list(values)
1
[a, b]
2
[c, d]
3
[e, f]
or, for batchSize = 3
id
values
group_id
1
a
1
2
b
1
3
c
1
4
d
2
5
e
2
6
f
2
out
group_id
collect_list(values)
1
[a, b, c]
2
[d, e, f]
How do I generate this column group_id so I can collect the values and group by group_id?
You could use row_number and DIV to generate group_id
To expand my answer, we use the Integer division properties to get group id
Row_number will give consecutive Numbers from 1 to N
But we need the numbers to start with 0, so we subtract 1 of the row number
rownumber Div (3)
0 0
1 0
2 0
3 1
4 1
5 1
6 2
This can be proven to be true for all integers to infinity
As group_id must start with 1(not necessary actually) we need to add anither 1 to the result
After with the resulting Group-id you can collect_list(values) tpo get your arrays
SELECT
id, `values`,
((ROW_NUMBER() OVER (ORDEr By id) -1) DIV 3) + 1 group_id
FROM tab1
id
values
group_id
1
a
1
2
b
1
3
c
1
4
d
2
5
e
2
6
f
2
7
g
3
8
h
3
9
i
3
SELECT
id, `values`,
((ROW_NUMBER() OVER (ORDEr By id) -1) DIV 2) + 1 group_id
FROM tab1
id
values
group_id
1
a
1
2
b
1
3
c
2
4
d
2
5
e
3
6
f
3
7
g
4
8
h
4
9
i
5
From my understanding what you're trying to do is chunking your selection.
Then this should do the trick: https://stackoverflow.com/a/29975781/21188126
How do i select all rows from a table where a specific column value equals something?
i have tried the following:
select from tablname where columnvalue = value
thanks
you could do:
q)table:([]a:1 2 3 4 5;b:`a`b`c`d`e;c:`hi`bye`bye`bye`hi)
q)table
a b c
-------
1 a hi
2 b bye
3 c bye
4 d bye
5 e hi
q)select from table where c=`bye
a b c
-------
2 b bye
3 c bye
4 d bye
You could do:
q)tbl:([] a:1 2 3;b:4 5 6;c:7 8 9)
q)tbl
a b c
-----
1 4 7
2 5 8
3 6 9
q)select a from tbl
a
-
1
2
3
I have my data that looks like this:
user_id touchpoint_number days_difference
1 1 5
1 2 20
1 3 25
1 4 10
2 1 2
2 2 30
2 3 4
I would like to create one more column that would create a cumulative sum of the days_difference, partitioned by user_id, but would reset whenever the value reaches 30 and starts counting from 0. I have been trying to do it, but I couldn't figure it out how to do it in PostgreSQL, because it has to be recursive.
The outcome I would like to have would be something like:
user_id touchpoint_number days_difference cum_sum_upto30
1 1 5 5
1 2 20 25
1 3 25 0 --- new count all over again
1 4 10 10
2 1 2 2
2 2 30 0 --- new count all over again
2 3 4 4
Do you have any cool ideas how this could be done?
This should do what you want:
with cte as (
select t.a, t.b, t.c, t.c as sumc
from t
where b = 1
union all
select t.a, t.b, t.c,
(case when t.c + cte.sumc > 30 then 0 else t.c + cte.sumc end)
from t join
cte
on t.b = cte.b + 1 and t.a = cte.a
)
select *
from cte
order by a, b;
Here is a rextester.
Suppose I have data formatted in the following way (FYI, total row count is over 30K):
customer_id order_date order_rank
A 2017-02-19 1
A 2017-02-24 2
A 2017-03-31 3
A 2017-07-03 4
A 2017-08-10 5
B 2016-04-24 1
B 2016-04-30 2
C 2016-07-18 1
C 2016-09-01 2
C 2016-09-13 3
I need a 4th column, let's call it days_since_last_order which, in the case where order_rank = 1 then 0 else calculate the number of days since the previous order (with rank n-1).
So, the above would return:
customer_id order_date order_rank days_since_last_order
A 2017-02-19 1 0
A 2017-02-24 2 5
A 2017-03-31 3 35
A 2017-07-03 4 94
A 2017-08-10 5 38
B 2016-04-24 1 0
B 2016-04-30 2 6
C 2016-07-18 1 79
C 2016-09-01 2 45
C 2016-09-13 3 12
Is there an easier way to calculate the above with a window function (or similar) rather than join the entire dataset against itself (eg. on A.order_rank = B.order_rank - 1) and doing the calc?
Thanks!
use the lag window function
SELECT
customer_id
, order_date
, order_rank
, COALESCE(
DATE(order_date)
- DATE(LAG(order_date) OVER (PARTITION BY customer_id ORDER BY order_date))
, 0)
FROM <table_name>
I have 2 tables :
1. transfer
2. data
in table data 2 records :
id name
1. 2 PQR
2. 3 XYZ
in table transfer 5 records :
id to from amount type
1. 1 2 3 100.00 C
2. 2 3 2 200.00 C
3. 3 2 3 150.00 D
4. 4 3 2 150.00 C
5. 5 2 3 300.00 D
now I want to form query that will take 2 in where condition and give me result
from transfer table that when 2 is in to column then from data should be shown
and when 2 is in from column then to data should be print.
And in result I want other columns that are amount and type.
I want data using join (Any), I am totally confused that how to perform this task.
Expected Result :
from/to amount type
3 100.00 C
3 200.00 C
3 150.00 D
3 300.00 D
Any Guidance on this..
Try Like this
select
case when "from"=2 then "to" when "to"=2 then "from" end "from/to"
,amount,type from transfer
Out put is
form/to amount type
3 100 C
3 200 C
3 150 D
3 150 C
3 100 D
OR
select case when "from"=2 then d.name when "to"=2 then data.name end "from/to",
amount,type from transfer inner join data on ("to"=data.id)
inner join data as d on("from"=d.id)
Out put is
form/to amount type
XYZ 100 C
XYZ 200 C
XYZ 150 D
XYZ 150 C
XYZ 100 D
ADDITION:
prove of working query: http://ideone.com/64kIov