I have a single table which stores data of orders:
Orders Table:
id | order_time | quantity | ...
1 | 1592821854318 | 2
2 | 1592901538199 | 4
3 | 1592966454547 | 1
4 | 1593081282406 | 9
5 | 1593141826330 | 6
order_time table is UNIX timestamp.
Using below query I am able to get available data grouped by days (86400000 = 24 hours):
SELECT order_time+ (86400000 - (order_time % 86400000)) as gap, SUM(quantity) as
totalOrdersBetweenInterval
FROM USAGE_DETAILS ud
WHERE order_time >= 1590969600 AND order_time <= 1593388799000
GROUP BY gap
ORDER BY gap ASC
Suppose for this month of June, I receive order on 1, 4, 6, 7 date then by using above query I am able to retrieve data as follow :
gap | totalOrdersBetweenInterval
1 | 5
4 | 6
6 | 4
7 | 10
I would receive UNIX timestamp in gap column but for the sake of example I have used readable dates.
Above query will only retrieve data for the days which would have received order but I want to split data in range like below which also include days with no orders :
gap | totalOrdersBetweenInterval
1 | 5
2 | 0
3 | 0
4 | 6
5 | 0
6 | 4
7 | 10
8 | 0
9 | 0
. | .
. | .
How do I go about that?
You need a query that returns 30 rows:1,2,...,30 for the days of June.
You could do it with a recursive CTE:
with days as (
select 1 day
union all
select day + 1
from days
where day < 30
)
but I'm not sure if Android uses a version of SQLite that supports CTEs.
If it does support them, all you need to do is join the CTE with a LEFT join to your query:
with
days as (
select 1 day
union all
select day + 1
from days
where day < 30
),
yourquery as (
<your query here>
)
select d.day, coalesce(t.totalOrdersBetweenInterval, 0) totalOrdersBetweenInterval
from days d left join yourquery t
on t.gap = d.day
If Android does not support CTEs you will have to build the query that returns the days with UNION ALL:
select d.day, coalesce(t.totalOrdersBetweenInterval, 0) totalOrdersBetweenInterval
from (
select 1 day union all select 2 union all
select 3 union all select 4 union all
......................................
select 29 union all select 30
) d left join (
<your query here>
) t
on t.gap = d.day
Thanks to #forpas for helping me out.
Just posting in case someone is searching for slicing data by unix time intervals.
with
days as (
select 1590969600000 day --Starting of June 1 2020
union all
select day + 86400000 --equivalent to 1 day
from days
where day < 1593388799000 --Less than 28th of June
),
subquery as (
SELECT order_time+ (86400000 - (order_time % 86400000)) as gap, SUM(quantity) as
totalOrdersBetweenInterval
FROM USAGE_DETAILS ud
WHERE order_time >= 1590969600000 AND order_time <= 1593388799000
GROUP BY gap
)
select d.day, coalesce(t.totalOrdersBetweenInterval, 0) totalOrdersBetweenInterval
from days d left join subquery t
on t.gap = d.day
order by d.day
Related
I have 2 tables in Kusto:
windowScans - each row is from this format : windowStart:long, windowEnd:long
files - each row is from this format: timestamp:long, fileId:string
I would like to join for each file all the windowScan rows that matches: timestamp > windowStart && timestamp < windowEnd.
The result should be a table of all files, and for each file all the matching pairs of windowScans.
It is possible that a windowScan row will appear in many files.
Any idea how to perform the query?
Here is one solution:
let windowsScan = datatable(windowStart:long, windowEnd:long)[1,5, 6,8, 10, 14];
let files = datatable(timestamp:long, fileId:string)[3,"a", 4,"b", 4,"c", 6, "a", 11,"a", 13, "b"];
windowsScan
| extend timestamp = range(windowStart, windowEnd, 1)
| mv-expand timestamp to typeof(long)
| join kind=inner (files) on timestamp
| summarize take_any(windowStart, windowEnd) by fileId, timestamp
Results:
fileId
timestamp
windowStart
windowEnd
a
3
1
5
b
4
1
5
c
4
1
5
a
6
6
8
a
11
10
14
b
13
10
14
Im trying to check how many times two teams have played against each other, while each appearing once at home and once away.
In the next table, we can see that Team 1 played against Team 2 three times, twice away and once at home, and Team 3 played against Team 4 twice, once away and once at home.
how can I do it using sqlite?
id_home
id_away
date
1
2
2/12
2
1
3/12
3
4
4/12
4
3
5/12
2
1
6/12
You can group by sorted pairings of the id_home and id_away teams:
with matches as (select distinct t1.id_home h, (select t2.id_away from teams t2 where t2.id_home = t1.id_home) a from teams t1), m1 as (select case when h < a then h else a end a1, case when a < h then h else a end a2 from matches)
select m1.a1 team1, m1.a2 team2, (select sum(m1.a1 = t3.id_home) from teams t3) home, (select sum(m1.a1 = t3.id_away) from teams t3) away from m1 group by m1.a1, m1.a2;
Output:
team1 | team2 | home | away
1 2 1 2
3 4 1 1
Here is my table - PK is (Con_num, version, order) :
Con_num version operation amount
15 1 A 1
15 1 B 2
15 1 C 3
15 2 A 4
15 3 A 5
15 3 B 6
15 4 C 7
Con_num is the contract number.
version is the version number.
operation is just an ID for an operation.
amount is the amount of the operation.
I would like to have the total amount per version. The tricky part is that: for version 1, i just have to sum the amount. But for version 2, I need to sum the version 2 line (with operation = A) and to take the two lines from version 1 (with operation != A). Therefore, for version 3, i will take the two lines of version 3, and only the line with operation = C from version 1. Any new operation invalidate the one from the previous versions.
The result will be:
Con_num version amount
15 1 6 (1 + 2 + 3)
15 2 9 (4 + 2 + 3)
15 3 14 (5 + 6 + 3)
15 4 18 (5 + 6 + 7)
How can I do that ?
For each con_num and version add up all records
for the same con_num
with no version greater than the version in question
having the highest version per operation
To get the amount of the record with the highest version can be solved with Oracle's KEEP FIRST/LAST:
select
base.con_num,
base.version,
(
select sum(max(mytable.amount) keep (dense_rank last order by mytable.version))
from mytable
where mytable.con_num = base.con_num
and mytable.version <= base.version
group by mytable.con_num, mytable.operation
) as total
from (select distinct con_num, version from mytable) base;
select
Con_num, version, orderno, a0+a1+a2 as amount
from (
select
Con_num, version, orderno
, lag(amount,2) over(partition by Con_num order by version, orderno) a2
, lag(amount,1) over(partition by Con_num order by version, orderno) a1
, amount a0
, row_number() over(partition by Con_num, version order by orderno desc) as rn
from table1
) d
where rn = 1
You seem to want only the "most recent" combinations of (Con_num, version, orderno) which can be identified using row_number() and the values required established using lag(,1) and lag(,2) but I don't reach the stated result.
result:
| con_num | version | orderno | amount |
|---------|---------|---------|--------|
| 15 | 1 | 3 | 37 |
| 15 | 2 | 1 | 42 |
| 15 | 3 | 2 | 35 |
sqlfiddle example
Using LAST_VALUE analytic function.
select con_num, version, q1+q2+q3
from (
select x.*,
last_value(case when operation = 1 then amount end) ignore nulls over (order by version) q1,
last_value(case when operation = 2 then amount end) ignore nulls over (order by version) q2,
last_value(case when operation = 3 then amount end) ignore nulls over (order by version) q3
from x
)
group by con_num,version, q1, q2, q3
order by con_num,version;
For example we have this 2 tables
table1:
Dir_num | dir_name
10 | john
11 | vlad
table2:
game | dir_num
101 | 10
111 | 10
102 | 11
104 | 10
104 | 10
Now I try to find the dir_name who has less than 2 games played.
select * from table1 where dir_num ....
Please help me find pl/sql code.
The output should show
Vlad.
Try something like this -- use GROUP BY and HAVING:
SELECT t.dir_num, t.dir_name
FROM Table1 t
LEFT JOIN Table2 t2 ON t.dir_num = t2.dir_num
GROUP BY t.dir_num, t.dir_name
HAVING COUNT(DISTINCT t2.game) < 2
And here is the SQL Fiddle.
If you want those in both tables (meaning at least 1 game), then change LEFT JOIN to INNER JOIN.
Good luck.
Please try:
SELECT t.dir_num, t.dir_name
FROM Table1 t
INNER JOIN Table2 t2 ON t.dir_num = t2.dir_num
GROUP BY t.dir_num, t.dir_name
HAVING COUNT(DISTINCT t2.game) < 2
I have two tables Say Table -A and table-B
Table-A having
Userid | Date
|
101 | 15 Aug ,2011
102 | 15 Aug ,2011
103 | 16 Aug ,2011
104 | 16 Aug ,2011
105 | 17 Aug ,2011
Table -B
Userid(f.k) | sts
101 | x
102 | y
101 | z
103 | x
101 | y
Required output is
Table-C
I want table c output as
DAte ,Total ,Sts as X,Sts as y, Avg of
Date | Total | Sts (if=x) |Sts (if=y) |Avg (Total/2)
15 Aug| 20 | 15 |5 |10
16aug | 30 | 22 |8 |15
I tried using :
select Date, select case when [Tasble-B].Sts='x' Then 0 else 1 END as StsX,select case when [Tasble-B].Sts='Y' Then 0 else 1 END as StsY,Total/2
from
Table-A
inner join Table-B on Table-A.UserID = Table-B.UserID
b group by RegDate
I am getting Error , I am Stuck with this query.Please Help
Thanks in advance
select Date,
select case when [Tasble-B].Sts='x' Then 0
else 1
END as StsX,
select case when [Tasble-B].Sts='Y' Then 0
else 1
END as StsY,
Total/2
from Table-A
inner join Table-B
on Table-A.UserID = Table-B.UserID
b group by RegDate
You do group by RegDate so I assume you should use RegDate in the field list instead of Date or perhaps RegDate as Date.
You are missing the total column. You could do that with count(*) as Total
Your select case ... statements should not be select's but sum(case ...)
Total/2, where does Total come from? My guess is that you want the average of StsX and StsY but it could also mean that you want to use the calculated Total column and divide that by 2. If that is the case you need to repeat your aggregate statement count(*)/2 or you could use this entire query as a sub-query and do the calculation using the field Total as you already do, Total/2.
Your table names need to be encapsulated in brackets [Table-B].
You have an extra b before the group by clause. You should remove that.
`
you can try:
select [Date],
(SUM(case when B.Sts='x' Then 1
else 0
END) +
SUM( case when B.Sts='Y' Then 1
else 0
END)) AS Total,
SUM( case when B.Sts='x' Then 1
else 0
END) AS StsX,
SUM( case when B.Sts='Y' Then 1
else 0
END) as StsY,
(SUM(case when B.Sts='x' Then 1
else 0
END) +
SUM( case when B.Sts='Y' Then 1
else 0
END))
/2.0 AS Average
from A
inner join B
on A.UserID = B.UserID
group by [Date]
I tested it with:
WITH A (UserId, [Date]) AS (
SELECT 101, '2011-08-15'
UNION
SELECT 102, '2011-08-15'
UNION
SELECT 103, '2011-08-16'
UNION
SELECT 104, '2011-08-16'
UNION
SELECT 105, '2011-08-17'
),
B (UserId, sts) AS
(
SELECT 101, 'x'
UNION
SELECT 102, 'y'
UNION
SELECT 101, 'z'
UNION
SELECT 103, 'x'
UNION
SELECT 101, 'y'
)
select [Date],
(SUM(case when B.Sts='x' Then 1
else 0
END) +
SUM( case when B.Sts='Y' Then 1
else 0
END)) AS Total,
SUM( case when B.Sts='x' Then 1
else 0
END) AS StsX,
SUM( case when B.Sts='Y' Then 1
else 0
END) as StsY,
(SUM(case when B.Sts='x' Then 1
else 0
END) +
SUM( case when B.Sts='Y' Then 1
else 0
END))
/2.0 AS Average
from A
inner join B
on A.UserID = B.UserID
group by [Date]