Battery % time charging
90 t1 yes
91 t2 yes
95 t3 no
89 t4 no
87 t5 no
80 t6 no
78 t7 yes
85 t8 yes
50 t9 no
40 t10 no
38 t11 no
20 t12 yes
I want to calculate battery depletion rate as :
change in battery / time taken
This should be calculated for ALL the windows when charging is 'no' (sandwiched in between 2 "yes"), and then the average of those rates should be taken.
So, for this dataset it should be:
95 - 80 / t6 - t3 = rate 1
50 - 38 / t11 - t9 = rate 2
average rate = ( rate 1 + rate 2 ) / 2
Please note there can be more than 2 windows of no's in the data
Here is my current code -
select ((max(battery_Percentage) - min (battery_Percentage)) / NULLIF(Extract(epoch FROM (max(time) - min(time))/3600),0)) as rate_of_battery_decline
from table
where
table.charging = 'no'
but this is not taking into account windows of no's in between the yes's as I want. Please help.
You have to separate the runs between the charging = 'yes' blocks:
with discharge_intervals as (
select battery_pct, tstamp,
sum((charging = 'yes')::int) over (order by tstamp) as ival_number,
charging = 'no' as keep
from cstats
), interval_rates as (
select ival_number,
(max(battery_pct) - min(battery_pct))
/ extract(epoch from max(tstamp) - min(tstamp)) as ival_rate
from discharge_intervals
where keep
group by ival_number
)
select avg(ival_rate)
from interval_rates;
Fiddle Here
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 ********
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.
can somebody help with a query for below problem
Return Table
Id Factor monthlyReturns price date
A1 0.2 0.001 2010-01-29
A1 0.2 0.003 2010-02-26
A1 0.2 0.004 2010-03-31
A1 0.2 0.004 2010-04-30
A2 0.1 0.001 2010-01-29
A2 0.1 0.001 2010-02-26
A2 0.1 0.001 2010-03-31
A2 0.1 0.001 2010-04-30
A3 0.3 0.03 2010-01-29
A3 0.3 0.04 2010-02-26
A3 0.3 0.05 2010-03-31
A3 0.3 0.05 2010-04-30
A4 0.4 0.12 2010-01-29
A4 0.4 0.12 2010-02-26
A4 0.4 0.14 2010-03-31
A4 0.4 0.15 2010-04-30
I want to convert this data into following format .Can somebody please suggest a query
A1 A2 A3 A4 Total
31-Jan-10 0.001 0.001 0.03 0.12 0.001*0.2(Factor for A1)+0.001*0.1(Factor forA2)+
0.03*0.3(Factor forA3)+ 0.12*0.4(Factor forA4)
28-Feb-10 0.003 0.001 0.04 0.12 Same as above
31-Mar-10 0.004 0.001 0.05 0.14 Same as above
30-Apr-10 0.004 0.001 0.05 0.15 Same as above
Thanks
below is the query you asked for, notice that you need to change the table name to yours.
a little explanation:
I assumed the Ids are limited to A1,A2,A3,A4. otherwise this will not work and you will need a more complexed solution.
first i created a common table expression of a pivoted table with all the factors grouped by date (assuming that there can not be two factors to the same id on the same date)
then, i join that with a pivoted table that holds all the monthly returns.
note: i used the sum function on the fields A1,A2,.. since i needed to group it by date and the select can only use aggregate function if the column is not in the group by clause.
this does not effect the values since you only have one row for each id on a particular date, but correct me if i'm wrong.
with FactorsByDate(PriceDate,FactorA1,FactorA2,FactorA3,FactorA4)
AS
(
SELECT [price date] AS Date,
SUM([A1]) AS A1, SUM([A2]) AS A2, SUM([A3]) AS A3, SUM([A4]) AS A4
FROM
(SELECT Id, Factor , [price date]
FROM TempTbl) AS SourceTable
PIVOT
(
SUM(Factor)
FOR Id IN ([A1], [A2], [A3], [A4])
) AS PivotTable
group by [price date]
)
SELECT Date,A1,A2,A3,A4, A1*FactorA1 + A2*FactorA2 + A3*FactorA3 + A4*FactorA4 AS Total
FROM
(
SELECT [price date] AS Date,
SUM([A1]) AS A1, SUM([A2]) AS A2, SUM([A3]) AS A3, SUM([A4]) AS A4
FROM
(SELECT Id, monthlyReturns , [price date]
FROM TempTbl) AS SourceTable
PIVOT
(
SUM(monthlyReturns)
FOR Id IN ([A1], [A2], [A3], [A4])
) AS PivotTable
group by [price date]
) AS monthlyReturns
INNER JOIN FactorsByDate ON FactorsByDate.PriceDate = monthlyReturns.Date
I have four tables
TABLE_A
----------------
ID AName1 AName2
1 A11 A12
2 A21 A22
3 A31 A32
TABLE_B
------------
AID ID BName
1 B11 Ba11
1 B12 Ba12
1 B13 Ba13
1 B14 Ba14
2 B21 Ba21
2 B22 Ba22
3 B31 Ba31
TABLE_C
----------------
AID BID ID CName
1 B11 C11 Ca11
1 B11 C12 Ca12
1 B11 C13 Ca13
1 B12 C14 Ca14
1 B13 C15 Ca15
1 B13 C16 Ca16
1 B14 C17 Ca17
1 B14 C18 Ca18
1 B14 C19 Ca19
2 B21 C20 Ca20
2 B21 C21 Ca21
2 B22 C22 Ca22
2 B22 C23 Ca23
2 B22 C24 Ca24
2 B22 C25 Ca25
TABLE_D
----------------
AID BID ID DName
1 B11 D1 Da1
1 B11 D2 Da2
1 B11 D3 Da3
1 B12 D4 Da4
1 B12 D5 Da5
1 B13 D6 Da6
1 B13 D7 Da7
1 B13 D8 Da8
1 B13 D9 Da9
1 B14 D10 Da10
2 B21 D11 Da11
2 B21 D12 Da12
2 B21 D13 Da13
2 B22 D14 Da14
2 B22 D15 Da15
Given a single pair of AName1 and AName2, I would like to get unique values of BName and the corresponding arrays of CName and DName.
For example, given AName1 = A21 and AName2 = A22, I would like to get the following:
BName CName DName
B21 {Ca20, Ca21} {Da11, Da12, Da13}
B22 {Ca22, Ca23, Ca24, Ca25} {Da14, Da15}
I'm currently using the following query:
SELECT
b.BName,
array_agg(c.CName),
array_agg(d.DName)
FROM
TABLE_B
INNER JOIN
TABLE_A on b.AID=TABLE_A.ID
LEFT JOIN
TABLE_C c on c.BID = b.ID
LEFT JOIN
TABLE_D d on d.BID=b.ID
WHERE
TABLE_A.AName1 like 'A21' AND
TABLE_A.AName2 like 'A22'
GROUP BY
b.ID
This is repeating values as if it is also grouping on C and D:
BName CName DName
B21 {Ca20, Ca20, Ca20, Ca21, Ca21, Ca21} {Da11, Da12, Da13, Da11, Da12, Da13}
Does anyone know how I might be able to correct this issue? I'm using PostgreSQL version 9.2.
SQL Fiddle
select
b.bname,
array_agg(distinct c.cname),
array_agg(distinct d.dname)
from
table_b b
inner join
table_a a on b.aid = a.id
left join
table_c c on c.bid = b.id
left join
table_d d on d.bid = b.id
where
a.aname1 = 'A21' and
a.aname2 = 'A22'
group by b.bname