I am planning to store query data in sqlite3 database.
I have these fields in sqlite3
UNIX_EPOCH, CUMULATIVE_QUERY_RATE
1452128581, 150
1452128582, 190
1452128583, 220
1452128584, 270
I want to get queries-per-second column as below:
QPS
0
40
30
50
how do I do it in sqlite3.
You simply have to subtract the value of the previous second:
SELECT unix_epoch,
(SELECT T1.cumulative_query_rate - T2.cumulative_query_rate
FROM SuperSecretTableName AS T2
WHERE T1.unix_epoch - 1 = T2.unix_epoch
) AS qps
FROM SuperSecretTableName AS T1;
Related
I have a big table which is 100k rows in size and the PRIMARY KEY is of the datatype NUMBER. The way data is populated in this column is using a random number generator.
So my question is, can there be a possibility to have a SQL query that can help me with getting partition the table evenly with the range of values. Eg: If my column value is like this:
1
2
3
4
5
6
7
8
9
10
And I would like this to be broken into three partitions, then I would expect an output like this:
Range 1 1-3
Range 2 4-7
Range 3 8-10
It sounds like you want the WIDTH_BUCKET() function. Find out more.
This query will give you the start and end range for a table of 1250 rows split into 20 buckets based on id:
with bkt as (
select id
, width_bucket(id, 1, 1251, 20) as id_bucket
from t23
)
select id_bucket
, min(id) as bkt_start
, max(id) as bkt_end
, count(*)
from bkt
group by id_bucket
order by 1
;
The two middle parameters specify min and max values; the last parameter specifies the number of buckets. The output is the rows between the minimum and maximum bows split as evenly as possible into the specified number of buckets. Be careful with the min and max parameters; I've found poorly chosen bounds can have an odd effect on the split.
This solution works without width_bucket function. While it is more verbose and certainly less efficient it will split the data as evenly as possible, even if some ID values are missing.
CREATE TABLE t AS
SELECT rownum AS id
FROM dual
CONNECT BY level <= 10;
WITH
data AS (
SELECT id, rownum as row_num
FROM t
),
total AS (
SELECT count(*) AS total_rows
FROM data
),
parts AS (
SELECT rownum as part_no, total.total_rows, total.total_rows / 3 as part_rows
FROM dual, total
CONNECT BY level <= 3
),
bounds AS (
SELECT parts.part_no,
parts.total_rows,
parts.part_rows,
COALESCE(LAG(data.row_num) OVER (ORDER BY parts.part_no) + 1, 1) AS start_row_num,
data.row_num AS end_row_num
FROM data
JOIN parts
ON data.row_num = ROUND(parts.part_no * parts.part_rows, 0)
)
SELECT bounds.part_no, d1.ID AS start_id, d2.ID AS end_id
FROM bounds
JOIN data d1
ON d1.row_num = bounds.start_row_num
JOIN data d2
ON d2.row_num = bounds.end_row_num
ORDER BY bounds.part_no;
PART_NO START_ID END_ID
---------- ---------- ----------
1 1 3
2 4 7
3 8 10
So my situation. Got a table with few thousand entries, I took one column and counted the number of the same entries.
SELECT mycolumn, COUNT(*)
FROM mytable
WHERE myid = 6867
GROUP BY mycolumn
ORDER BY COUNT(*) DESC
Outputs:
6 885
1 715
4 562
5 557
2 232
3 181
I get the desired results. Now all I need is to add a bottom row with a sum of all counted entries.
Typically you would do this in some reporting tool, like SSRS, not SQL.
To do it in SQL, add a UNION statement:
UNION ALL
SELECT 0, COUNT(*)
FROM mytable
WHERE myid = 6867;
I need a query to update the value at the point from which the metrics rises or decreases .For example I have a table with
ID METRICS INDICATOR
1 204.4
2 205
3 206 H
4 204
5 199
6 198 L
7 204
8 205 H
9 201
10 199
If you see the above table the metrics column the reversal of metrics happens . The point the reversal happens should be updated with the indicator value H/L as shown in the indicator column.
You want a "H" when both the preceding and the following rows have smaller values:
UPDATE MyTable
SET Indicator = 'H'
WHERE Metrics > (SELECT Metrics
FROM MyTable AS T2
WHERE T2.ID < MyTable.ID
ORDER BY ID DESC
LIMIT 1)
AND Metrics > (SELECT Metrics
FROM MyTable AS T2
WHERE T2.ID > MyTable.ID
ORDER BY ID ASC
LIMIT 1);
You want a "L" when both the preceding and the following rows have larger values; use a similar query.
i have a table ops containing operations on an account, the balance of this account and an index giving the chronological order of these operations.
idx op_sum account_balance
1 200 200
2 -30 170
4 -20 160 -- this operation has idx=4 so the balance is accurate!
3 10 180
A trigger is ensuring that idx stays unique.
CREATE TRIGGER on_insert_before BEFORE INSERT ON ops
WHEN (SELECT op_sum FROM ops WHERE idx=NEW.idx)
BEGIN
UPDATE ops SET idx=idx+1 WHERE idx>=NEW.idx;
END;
I now want to add a trigger that could calculate the account_balance when adding a new operation while considering the chronological order and updating the rows with a superior idx if any.
As an example if i do this: INSERT INTO ops(idx, op_sum) VALUES(2,-90);
my table should look like that:
idx op_sum account_balance
1 200 200
3 -30 80
5 -20 70
4 10 90
2 -90 110
I tried things like that:
CREATE TRIGGER on_insert_after AFTER INSERT ON ops
FOR EACH ROW
BEGIN
UPDATE ops SET account_balance=
(CASE WHEN idx=1
THEN op_sum
ELSE (SELECT account_balance FROM ops WHERE idx=idx-1)+op_sum
END);
END;
But it didn't work (to be more exact this part doesn't work (SELECT account_balance FROM ops WHERE idx=idx-1)).
I have also been experimenting with recursive common table expressions, that would give me the accurate results:
WITH RECURSIVE
cnt(x,y,z) AS (VALUES(1,200,200) UNION ALL
SELECT
x+1,
(SELECT op_sum FROM ops WHERE idx=x+1),
z+(SELECT op_sum FROM ops where idx=x+1)
FROM cnt where x<(select max(idx) from ops))
SELECT x,y,z FROM cnt;
But i would like to know if there is a way to do it inside of my table, with triggers.
To get the new value from a different row, you must use a correlated subquery:
UPDATE ops SET account_balance=
(CASE WHEN idx=1
THEN op_sum
ELSE op_sum + (SELECT account_balance
FROM ops AS previous_ops
WHERE previous_ops.idx = ops.idx - 1)
END);
I have a sample table with following values
SNO | Mon
-----+-------
100 | 1
101 | 1
102 | 1
100 | 2
101 | 2
102 | 2
100 | 3
101 | 3
Now I need a query to count the total sno's which are in 3 months
The result should be 2, as 100 & 101 are in mon 1,2 and 3. However, 102 is only present in mon 1,2.
Thanks,
RK
This Query in theory should work.
SELECT
tmpTbl.sNo
FROM
tmpTbl
GROUP BY
tmpTbl.sNo
HAVING
Count(tmpTbl.monNo) = (SELECT Count(*) FROM (SELECT tmpTbl.monNo FROM tmpTbl GROUP BY tmpTbl.monNo));
The result would be,
sNo
----
100
101
I have used two SubQueries to get the result. Teh both are used in the HAVING clause of the SQL. First SqubQuery (inner most). Will get the number of Unique Month's available in your table, the outer SubQuery will then Count the number of Unique months. So the Overall Query can be translated as "SELECT the serial number FROM the table HAVING the Count of Month equal to the Number of unique records in the same table".
The reason I used SbQuery instead of a number is because of the fact this will also be applicable when your month number increases. Hope this helps !
EDIT
Here is the Query for getting the count.
SELECT
Count(*) As simpleCount
FROM
(
SELECT
tmpTbl.sNo
FROM
tmpTbl
GROUP BY
tmpTbl.sNo
HAVING
Count(tmpTbl.monNo) = (SELECT Count(*) FROM (SELECT tmpTbl.monNo FROM tmpTbl GROUP BY tmpTbl.monNo))
);