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'