SQLite: Summary data of a query result - sqlite

I have the following query that provides me with the 10 most recent records in the database:
SELECT
dpDate AS Date,
dpOpen AS Open,
dpHigh AS High,
dpLow AS Low,
dpClose AS Close
FROM DailyPrices
WHERE dpTicker = 'DL.AS'
ORDER BY dpDate DESC
LIMIT 10;
The result of this query is as follows:
bash-3.2$ sqlite3 myData < Queries/dailyprice.sql
Date Open High Low Close
---------- ---------- ---------- ---------- ----------
2016-06-13 4.0 4.009 3.885 3.933
2016-06-10 4.23 4.236 4.05 4.08
2016-06-09 4.375 4.43 4.221 4.231
2016-06-08 4.406 4.474 4.322 4.35
2016-06-07 4.377 4.466 4.369 4.384
2016-06-06 4.327 4.437 4.321 4.353
2016-06-03 4.34 4.428 4.316 4.335
2016-06-02 4.434 4.51 4.403 4.446
2016-06-01 4.51 4.512 4.317 4.399
2016-05-31 4.613 4.67 4.502 4.526
bash-3.2$
Whilst I need to plot the extracted data, I also need to obtain the following summary data of the dataset:
Minimum date ==> 2016-05-31
Maximum date ==> 2016-06-13
Open value at minimum date ==> 4.613
Close value at maximum date ==> 3.933
Maximum of High column ==> 4.67
Minimum of Low column ==> 3.885
How can I, as newbie, approach this issue? Can this be done in one query?
Thanks for pointing me in the right direction.
Best regards,
GAM

The desired output can be achieved with
aggregate functions on a convenient common table expression,
which uses OPs expression verbatim
OPs method, with limit 1 applied to common table expression,
for getting mindate and maxdate among the ten days
Query:
WITH Ten(Date,Open,High,Low,Close) AS
(SELECT dpDate AS Date,
dpOpen AS Open,
dpHigh AS High,
dpLow AS Low,
dpClose AS Close
FROM DailyPrices
WHERE dpTicker = 'DL.AS'
ORDER BY dpDate DESC LIMIT 10)
SELECT min(Date) AS mindate,
max(Date) AS maxdate,
(SELECT Open FROM Ten ORDER BY Date ASC LIMIT 1) AS Open,
max(High) AS High,
min(Low) AS Low,
(SELECT Close FROM Ten ORDER BY Date DESC LIMIT 1) AS Close
FROM Ten;
Output (.headers on and .mode column):
mindate maxdate Open High Low Close
---------- ---------- ---------- ---------- ---------- ----------
2016-05-31 2016-06-13 4.613 4.67 3.885 3.933
Note:
I think the order of values in OPs last comment do not match the order of columns in the preceding comment by OP.
I chose the order from the preceding comment.
The order in the last comment seems to me to be "mindate, maxdate, Open, Close, High, Low".
Adapting my proposed query to that order would be simple.
Using SQLite 3.18.0 2017-03-28 18:48:43
Here is the .dump of my toy database, i.e. my MCVE, in case something is unclear. (I did not enter the many decimal places, it is probably a float rounding thing.)
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE dailyPrices (dpDate date, dpOpen float, dpHigh float, dpLow float, dpClose float, dpTicker varchar(10));
INSERT INTO dailyPrices(dpDate,dpOpen,dpHigh,dpLow,dpClose,dpTicker) VALUES('2016-06-13',4.0,4.009000000000000341,3.8849999999999997868,3.9329999999999998294,'DL.AS');
INSERT INTO dailyPrices(dpDate,dpOpen,dpHigh,dpLow,dpClose,dpTicker) VALUES('2016-06-10',4.2300000000000004263,4.2359999999999997655,4.0499999999999998223,4.080000000000000071,'DL.AS');
INSERT INTO dailyPrices(dpDate,dpOpen,dpHigh,dpLow,dpClose,dpTicker) VALUES('2016-06-09',4.375,4.4299999999999997157,4.2210000000000000852,4.2309999999999998721,'DL.AS');
INSERT INTO dailyPrices(dpDate,dpOpen,dpHigh,dpLow,dpClose,dpTicker) VALUES('2016-06-08',4.4059999999999996944,4.4740000000000001989,4.3220000000000000639,4.3499999999999996447,'DL.AS');
INSERT INTO dailyPrices(dpDate,dpOpen,dpHigh,dpLow,dpClose,dpTicker) VALUES('2016-06-07',4.3769999999999997797,4.4660000000000001918,4.3689999999999997726,4.384000000000000341,'DL.AS');
INSERT INTO dailyPrices(dpDate,dpOpen,dpHigh,dpLow,dpClose,dpTicker) VALUES('2016-06-06',4.3269999999999999573,4.4370000000000002771,4.3209999999999997299,4.3529999999999997584,'DL.AS');
INSERT INTO dailyPrices(dpDate,dpOpen,dpHigh,dpLow,dpClose,dpTicker) VALUES('2016-06-03',4.3399999999999998578,4.4370000000000002771,4.3209999999999997299,4.3529999999999997584,'DL.AS');
INSERT INTO dailyPrices(dpDate,dpOpen,dpHigh,dpLow,dpClose,dpTicker) VALUES('2016-06-02',4.4340000000000001634,4.5099999999999997868,4.4029999999999995807,4.4459999999999997299,'DL.AS');
INSERT INTO dailyPrices(dpDate,dpOpen,dpHigh,dpLow,dpClose,dpTicker) VALUES('2016-06-01',4.5099999999999997868,4.5119999999999995665,4.3170000000000001705,4.3990000000000000213,'DL.AS');
INSERT INTO dailyPrices(dpDate,dpOpen,dpHigh,dpLow,dpClose,dpTicker) VALUES('2016-05-31',4.6130000000000004334,4.6699999999999999289,4.5019999999999997797,4.525999999999999801,'DL.AS');
COMMIT;

Related

How to convert clickhouse date understandable to Grafana graph?

My Query is below:
SELECT
(date),
CVC_Demand_Per_Subscriber
FROM
(SELECT
date,
sum(Max_Utilization) as SUM_Max_Util,
sum(AVC) as SUM_Total_Active_AVCs,
(SUM_Max_Util/SUM_Total_Active_AVCs) as CVC_Demand_Per_Subscriber
FROM
(
SELECT
date,
cvc as CVC,
avc as AVC,
bandwidth,
round((max(lout)/1000000),2) as Max_Utilization,
((((max(lout) / bandwidth) * 100)) / 1000000) as Max_Utilization_Percent,
(Max_Utilization/AVC) as CVC_Demand_Per_Subscriber
FROM
(
SELECT
date,
path[2] as cvc,
bandwidth,
avc,
max(load_out) as lout
FROM noc.interface
ANY INNER JOIN
(
SELECT
cvcid as cvc,
bandwidth,
activeavc as avc
FROM dictionaries.nsi_cvcs
GROUP BY
cvc,
avc,
bandwidth
) USING cvc
WHERE
managed_object IN (
SELECT bi_id
FROM dictionaries.managedobject
WHERE nbn = 1)
AND(date >= today()- 7)
GROUP BY
date,
cvc,
avc,
bandwidth
ORDER BY
date,
cvc,
avc
)
GROUP BY
date,
cvc,
avc,
bandwidth
)
GROUP BY date
ORDER BY date ASC)
tmp
I am getting the result data when i select Table in Grafana like below:
Time CVC_Demand_Per_Subscriber
2021-07-19 00:00:00 1.61
2021-07-18 00:00:00 2.70
2021-07-17 00:00:00 2.90
2021-07-16 00:00:00 2.83
2021-07-15 00:00:00 2.54
2021-07-14 00:00:00 2.38
2021-07-13 00:00:00 2.39
2021-07-12 00:00:00 0.64
But when i change it to Graph, i dont see the graph plotted with the values, according to the dates. It does not say "no data" but an empty graph.
Please Help me where i am wrong?
I tried the below but no luck:
Converted the date with UNIX_TIMESTAMP
to_char(date_format)
$__timeGroup()
$__time
Please also suggest optimization on the query.
It needs to:
define Column:DateTime as Time
set the sql-query
SELECT
$timeSeries as t,
sum(CVC_Demand_Per_Subscriber) value
FROM (
/* emulate the test dataset */
SELECT toDateTime(data.1) AS Time, data.2 AS CVC_Demand_Per_Subscriber
FROM (
SELECT arrayJoin([
('2021-07-19 00:00:00', 1.61),
('2021-07-18 00:00:00', 2.70),
('2021-07-17 00:00:00', 2.90),
('2021-07-16 00:00:00', 2.83),
('2021-07-15 00:00:00', 2.54),
('2021-07-14 00:00:00', 2.38),
('2021-07-13 00:00:00', 2.39),
('2021-07-12 00:00:00', 0.64)]) as data)
)
WHERE $timeFilter
GROUP BY t
ORDER BY t
When the graph is empty (displayed 'No data') and no query error need to check ClickHouse Datasource settigs to make sure that Add CORS flag to requests is enabled:

SELECT in SELECT

I have the following query which I am trying to rewrite:
SELECT
max(dpHigh) AS High
FROM DailyPrices
WHERE dpTicker = 'DL.AS'
AND dpDate IN
(SELECT
dpDate
FROM DailyPrices
WHERE dpTicker ='DL.AS'
ORDER BY update DESC
LIMIT 10);
The query gives me the required result:
bash-3.2$ sqlite3 myData < Queries/high.sql
High
----------
4.67
bash-3.2$
Since next to the high value I wish to expand this query to also obtain a low value, earliest date, latest date, etc. For this reason, I am trying re-write an equivalent query using a select in select statement.
SELECT
(SELECT
max(dpHigh)
FROM DailyPrices
WHERE dpTicker = 'DL.AS'
AND dpDate IN
(SELECT dpDate
FROM DailyPrices
WHERE dpTicker ='DL.AS'
ORDER BY dpDate DESC
LIMIT 10)
)AS High
FROM DailyPrices
WHERE dpTicker = 'DL.AS';
Execution of the query spits output the expected value, however, it does exactly for the number of data entries of 'DL.AS'.
...
4.67
4.67
4.67
4.67
4.67
4.67
4.67
bash-3.2$
Since I am a SQLite newbie, I am probably overlooking the obvious. Does anybody have any suggestions?
BR
GAM
The outermost query looks like this:
SELECT (...)
FROM DailyPrices
WHERE dpTicker = 'DL.AS';
This will generate one output row for each table row with a matching dpTicker.
To generate a single row, regardless of how many rows might be found in some table, use a query without a FROM (the filtering and aggregation is already handled in the subqueries):
SELECT (...) AS High,
(...) AS Low;

SQLite how to select row based on a column max

I have the following table
UserID, Cost, date
1. 23. 2015-04-02
2. 17. 2015-03-14
1. 63. 2015-09-23
2. 49. 2013-03-17
2. 12. 2013-04-23
1. 96. 2016-01-01
What I want is a list of USERID & date with the largest cost
So
Userid 1 cost 96 date 2016-01-01
Userid 2 cost 49 date 2013-03-17
I have tried
select date, userid, max(cost) from table group by userid
But I'm confused with will the date always be from the correct row
Thanks
In SQLite 3.7.11 or later, values from other columns are guaranteed to come from a row that matches the max().
Consider a generalized approach for most RDMS versions. Below uses a derived table subquery:
SELECT t2.UserID, t2.MaxOfCost, t1.Date
FROM Table t1
INNER JOIN
(SELECT UserID, Max(Cost) As MaxOfCost,
FROM Table) t2
ON t1.UserID = t2.UserID
AND t1.Cost = t2.MaxOfCost

Find difference between rows of same column (difference between time data)

I want to find difference between time data which is in same column for group of same employee. I have written a query as below:
WITH rows AS
(
SELECT isnull(left(hhmm,2)+ ':'+ right(left(hhmm,4),2),'''') as login,
ROW_NUMBER() OVER (ORDER BY cardno) AS rn
FROM ATTN01072013_copy13_7_13
)
SELECT *--mc.login-mp.login as diff
FROM rows mc
JOIN rows mp
ON mc.rn = mp.rn - 1
This query will return data like this:
cardno login rn cardno login rn
E44920 09:18 1 E44920 09:46 2
E44920 09:46 2 E44920 17:09 3
E44920 17:09 3 E44920 16:57 4
E44920 16:57 4 E44920 17:34 5
E44920 17:34 5 E44920 17:53 6
E44920 17:53 6 E44920 17:56 7
E44920 17:56 7 E44920 17:57 8
E44920 17:57 8 E44920 18:00 9
Now I want to find difference between 1st and 2nd login time.. then 3rd and 4th login time. How can I do this, kindly suggest solution asap, thanks.
Solution:
DECLARE #Event TABLE(
EventID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
CardNo VARCHAR(10) NOT NULL,
[Login] DATETIME NOT NULL
-- To prevent duplicate events
-- This constraint will create an index used to optimize the RowNum and the last queries
UNIQUE(CardNo,[Login])
);
INSERT INTO #Event(CardNo,[Login])
SELECT 'E44920', '2013-07-15T09:18:00'
UNION ALL SELECT 'E44920', '2013-07-15T09:46:00'
UNION ALL SELECT 'E44920', '2013-07-15T17:09:00'
UNION ALL SELECT 'E44920', '2013-07-15T16:57:00'
UNION ALL SELECT 'E44920', '2013-07-15T17:34:00'
UNION ALL SELECT 'E44920', '2013-07-15T17:53:00';
DECLARE #EventWithRowNum TABLE(
RowNum INT NOT NULL,
CardNo VARCHAR(10) NOT NULL,
PRIMARY KEY (CardNo,RowNum),
[Login] DATETIME NOT NULL
UNIQUE(CardNo,[Login])
);
INSERT INTO #EventWithRowNum (CardNo,[Login],RowNum)
SELECT e.CardNo, e.[Login], ROW_NUMBER() OVER(PARTITION BY e.CardNo ORDER BY e.[Login]) AS RowNum
FROM #Event e;
-- Final query
SELECT crt.RowNum,
crt.CardNo,
crt.[Login] AS CurrentLogin,
nxt.RowNum,
nxt.[Login] AS NextLogin,
DATEDIFF(SECOND, crt.Login, nxt.Login) AS Diff_Seconds
FROM #EventWithRowNum crt -- crt = odd rows
LEFT JOIN #EventWithRowNum nxt ON crt.CardNo=nxt.CardNo AND crt.RowNum=nxt.RowNum-1 -- nxt = even rows
WHERE crt.RowNum % 2 = 1 -- odd rows; you could add a computed column Modulo2 AS (RowNum % 2) PERSISTED and then you could define a index (key: Modulo2, CardNo, Login)
ORDER BY crt.CardNo, crt.[Login];
Results:
RowNum CardNo Current_Login RowNum Next_Login Diff_Seconds
----------- ---------- ----------------------- ----------- ----------------------- ------------
1 E44920 2013-07-15 09:18:00.000 2 2013-07-15 09:46:00.000 1680
3 E44920 2013-07-15 16:57:00.000 4 2013-07-15 17:09:00.000 720
5 E44920 2013-07-15 17:34:00.000 6 2013-07-15 17:53:00.000 1140
Try:
DATEDIFF (mi, CAST(mc.login AS DATETIME), CAST(mp.login AS DATETIME)) as diff
This will get difference in minutes
SQLFiddle DEMO
Here is a fully query you can try using. As Nenad Zivkovic already shown, idea is to use DATEDIFF function for this.
Only difference is that I’d suggest using full date time for calculating the difference to avoid possible issues when one login is like 22:03 and other one is 00:16.
WITH rows AS
(
SELECT isnull(left(hhmm,2)+ ':'+ right(left(hhmm,4),2),'''') as login,
hhmm as Full_Login,
ROW_NUMBER() OVER (ORDER BY cardno) AS rn
FROM ATTN01072013_copy13_7_13
)
SELECT mc.login,
mc.rn,
DATEDIFF(mi,mc.Full_Login, mp.Full_Login)
mp.login,
mc.rn
FROM rows mc
JOIN rows mp
ON mc.rn = mp.rn

Query to perform date arithmetic on same field depending upon separate status field?

I have an Oracle table that contains data similar to the following:
ID | STATUS | TIME
-------------------------------
1 | IN | 2013/26/03 00:00
1 | OUT | 2013/26/03 07:00
1 | IN | 2013/27/03 03:00
2 | IN | 2013/26/03 01:00
2 | OUT | 2013/26/03 06:00
3 | IN | 2013/26/03 01:30
.
.
The STATUS represents check-in and check-out, where the ID represents individuals.
I've come up with a query using sub-queries but it seems inelegant and inefficient. Is it possible to write a single query (meaning no sub-queries) to calculate an elapsed time (IN -> OUT) for each ID?
UPDATE: Also, would it be possible to display the elapsed time the individual is OUT? For example in the data listed above Individual #1 is IN for 7 hours, but OUT for 20 hours (2013/27/03 03:00 - 2013/26/03 07:00). Since this would be calculated across records I'm not sure how this can be written.
try this
select timein.id, 24 * (timeout.time - timein.time) ElapsedTime
from t timein
left outer join t timeout on timein.id = timeout.id
where timein.status = 'IN' and timeout.status = 'OUT'
if your time field is char datatype then you need to do this
select timein.id, 24 * (TO_DATE(timeout.time, 'YYYY-DD-MM hh24:mi')
- TO_DATE(timein.time, 'YYYY-DD-MM hh24:mi')) ElapsedTime
from t timein
left outer join t timeout on timein.id = timeout.id
where timein.status = 'IN' and timeout.status = 'OUT'
try this for days with time
select timein.id, NUMTODSINTERVAL((timeout.time - timein.time),'day') ElapsedTime
from t timein
left outer join t timeout on timein.id = timeout.id
where timein.status = 'IN' and timeout.status = 'OUT'
For In and Out time you can use this and modify according to your data
with cte as
(
select t.id, status,
24 * (t.time - LAG(t.time)
OVER (partition by id ORDER BY t.time)) AS diff
from t
)
select t1.id, t1.diff timeIn, t2.diff timeOut
from cte t1
LEFT OUTER JOIN
cte t2 on t1.id = t2.id and t2.status = 'IN' and t2.diff is not null
where t1.status = 'OUT'

Resources