Oracle, Mysql, how to get average - sql

How to get Average fuel consumption only using MySQL or Oracle:
SELECT te.fuelName,
zkd.fuelCapacity,
zkd.odometer
FROM ZakupKartyDrogowej zkd
JOIN TypElementu te
ON te.typElementu_Id = zkd.typElementu_Id
AND te.idFirmy = zkd.idFirmy
AND te.typElementu_Id IN (3,4,5)
WHERE zkd.idFirmy = 1054
AND zkd.kartaDrogowa_Id = 42
AND zkd.data BETWEEN to_date('2015-09-01','YYYY-MM-DD')
AND to_date('2015-09-30','YYYY-MM-DD');
Result of this query is:
fuelName | fuelCapacity | odometer | tanking
-------------------------------------------------
'ON' | 534 | 1284172 | 2015-09-29
'ON' | 571 | 1276284 | 2015-09-02
'ON' | 470 | 1277715 | 2015-09-07
'ON' | 580.01 | 1279700 | 2015-09-11
'ON' | 490 | 1281103 | 2015-09-17
'ON' | 520 | 1282690 | 2015-09-23
We can do it later in java or php, but want to get result right away from query. How should we modify above query to do that?
fuelCapacity is the number of liters of fuel that has been poured into cartank at gas station.

For one total average, what you need is the sum of the refills divided by the difference between the odometer readings at the start and the end, i.e. fuel used / distance travelled.
I don't have your table structure at hand, but this alteration to the select statement should do the trick:
select cast(sum(zkd.fuelCapacity) as float) / (max(zkd.odometer) - min(zkd.odometer)) as consumption ...
The cast(field AS float) does what the name implies, and typecasts the field as float, so the result will also be a float. (I do suspect that your fuelCapacity field is a float because there is one float value in your example, but this will make sure.)

Related

Tracking Growth of a Metric over Time In TimescaleDB

I'm currently running timescaleDB. I have a table that looks similar to the following
one_day | name | metric_value
------------------------+---------------------
2022-05-30 00:00:00+00 | foo | 400
2022-05-30 00:00:00+00 | bar | 200
2022-06-01 00:00:00+00 | foo | 800
2022-06-01 00:00:00+00 | bar | 1000
I'd like a query that returns the % growth and raw growth of metric, so something like the following.
name | % growth | growth
-------------------------
foo | 200% | 400
bar | 500% | 800
I'm fairly new to timescaleDB and not sure what the most efficient way to do this is. I've tried using LAG, but the main problem I'm facing with that is OVER (GROUP BY time, url) doesn't respect that I ONLY want to consider the same name in the group by and can't seem to get around it. The query works fine for a single name.
Thanks!
Use LAG to get the previous value for the same name using the PARTITION option:
lag(metric_value,1,0) over (partition by name order by one_day)
This says, when ordered by 'one_day', within each 'name', give me the previous (the second parameter to LAG says 1 row) value of 'metric_value'; if there is no previous row, give me '0'.

Progress query to remove duplicates based on number of duplicates

Our accounting department needs pull tax data from our MIS every month and submit it online to the Dept. of Revenue. Unfortunately, when pulling the data, it is duplicated a varying number of times depending on which jurisdictions we have to pay taxes to. All she needs is the dollar amount for one jurisdiction, for one line, because she enters that on the website.
I've tried using DISTINCT to pull only one record of the type, in conjunction with LEFT() to pull just the first 7 characters of the jurisdiction but it ended up excluding certain results that should have been included. I believe it was because the posting date and the amount on a couple transactions was identical. They were separate transactions but the query took them as duplicates and ignored them.
Here is a couple of examples of queries I've run that have been successful in pulling most of the data, but most times either too much or not enough:
SELECT DISTINCT LEFT("Sales-Tax-Jurisdiction-Code", 7), "Taxable-Base", "Posting-Date"
FROM ARInvoiceTax
WHERE ("Posting-Date" >= '2019-09-01' AND "Posting-Date" <= '2019-09-30')
AND (("Sales-Tax-Jurisdiction-Code" BETWEEN '55001' AND '56763')
OR "Sales-Tax-Jurisdiction-Code" = 'Dakota Cty TT')
ORDER BY "Sales-Tax-Jurisdiction-Code"
Here is a query that I can to pull all of the data and the subsequent result is below that:
SELECT "Sales-Tax-Jurisdiction-Code", "Taxable-Base", "Posting-Date"
FROM ARInvoiceTax
WHERE ("Posting-Date" >= '2019-09-01' AND "Posting-Date" <= '2019-09-30')
AND (("Sales-Tax-Jurisdiction-Code" BETWEEN '55001' AND '56763')
OR "Sales-Tax-Jurisdiction-Code" = 'Dakota Cty TT')
ORDER BY "Sales-Tax-Jurisdiction-Code"
Below is a sample of the output:
Jurisdiction | Tax Amount | Posting Date
-------------|------------|-------------
5512100City | $50.00 | 2019-09-02
5512100City | $50.00 | 2019-09-03
5512100City | $70.00 | 2019-09-02
5512100Cnty | $50.00 | 2019-09-02
5512100Cnty | $50.00 | 2019-09-03
5512100Cnty | $70.00 | 2019-09-02
5512100State | $70.00 | 2019-09-02
5512100State | $50.00 | 2019-09-02
5512100State | $50.00 | 2019-09-03
5513100Cnty | $25.00 | 2019-09-12
5513100State | $25.00 | 2019-09-12
5514100City | $9.00 | 2019-09-06
5514100City | $9.00 | 2019-09-06
5514100Cnty | $9.00 | 2019-09-06
5514100Cnty | $9.00 | 2019-09-06
5515100State | $12.00 | 2019-09-11
5516100City | $6.00 | 2019-09-13
5516100City | $7.00 | 2019-09-13
5516100State | $6.00 | 2019-09-13
5516100State | $7.00 | 2019-09-13
As you can see, the data can be all over the place. One zip code could have multiple different lines. What the accounting department does now is prints a report with this information and, in a spreadsheet, only records (1) dollar amount per transaction. For example, for 55121, she would need to record $50.00, $50.00 and $70.00 (she tallies them and adds the total amount on the website) however the SQL query gives me those (3) numbers, (3) times.
I can't seem to figure out a query that will pull only one set of the data. Unfortunately, I can't do it based on the words/letters after the 00 because not all jurisdictions have all 3 (city, cnty, state) and thus trying to remove lines based on that removes valid lines as well.
Can you use select distinct? If the first five characters are the zip code and you just want that:
select distinct left(jurisdiction, 5), tax_amount
from t;
Take only City/County/.. whatever is first
select jurisdiction, tax_amount, Posting_Date
from (
select *, dense_rank() over(partition by left(jurisdiction, 7) order by substring(jurisdiction, 8, len(jurisdiction))) rnk
from taxes -- you output here
)
where rnk=1;
Sql server syntax, you may need other string functions in your dbms.
Postgresql fiddle

SQL syntax for removing a specific row [time] from a specific group [symbol]

I'm running up against the edge of my SQL Query knowledge and could use a point in the right direction. (I am using Presto, but ideally that shouldn't matter because Presto uses common SQL syntax.)
What I would like to do is always exclude the 9:31:00 [QuoteTime] ONLY on the 'VIX' Symbol. If possible, I would only like to exclude the 9:31:00 VIX [QuoteTime] row only IF the [Bid] AND [Ask] are 0.
I have looked into the HAVING clause as an alternative/addition to the WHERE clause. I was not successful in integrating this to my query.
I have looked into the LIKE clause in an effort to find the 9:31:00 time. I'm also concerned about my ability to write this efficiently.
My struggle is combining them to create the correct and most efficient query.
Here is my data:
+---------------+--------+---------+---------+
| QuoteTime | Symbol | Bid | Ask |
+---------------+--------+---------+---------+
| 09:31:00 | VIX | 0 | 0 |
| 09:32:00 | VIX | 13.24 | 13.24 |
| 09:33:00 | VIX | 13.21 | 13.21 |
| 09:31:00 | SPX | 2889.36 | 2894.18 |
| 09:32:00 | SPX | 2889.15 | 2892.99 |
| 09:33:00 | SPX | 2889.89 | 2892.71 |
| 09:31:00 | NDX | 7616.64 | 7616.64 |
| 09:32:00 | NDX | 7612.13 | 7612.13 |
| 09:33:00 | NDX | 7613.32 | 7613.32 |
+---------------+--------+---------+---------+
Here is my current query:
SELECT QuoteTime, Symbol, ((Bid+Ask)/2) as MidPoint
FROM schema.tablename
WHERE (Symbol IN ('SPX', 'VIX'))
Below is my nuclear option. I don't like it because it may (unbeknownst to me) remove other rows which contain 0s on other symbols at other times:
SELECT QuoteTime, Symbol, ((Bid+Ask)/2) as MidPoint
FROM schema.tablename
WHERE (Symbol IN ('SPX', 'VIX')) AND Bid != 0 AND Ask != 0
You want to select all rows for symbols 'SPX' and 'VIX', but exclude 9:31:00 - VIX - 0 - 0. There are several ways to express this. One way has been shown in fa06's answer.
SELECT quotetime, symbol, ((bid+ask)/2) as midpoint
FROM schema.tablename
WHERE symbol in ('SPX', 'VIX')
AND (quotetime, symbol, bid, ask) NOT IN ((time '09:31', 'VIX', 0, 0));
(EDIT: You say that this doesn't work for you. It may be that presto doesn't yet support the IN clause with tuples.)
Another is:
SELECT quotetime, symbol, ((bid+ask)/2) as midpoint
FROM schema.tablename
WHERE symbol IN ('SPX', 'VIX')
AND (quote_time <> time '09:31' OR symbol <> 'VIX' OR bid <> 0 OR ask <> 0);
Another is:
SELECT quotetime, symbol, ((bid+ask)/2) as midpoint
FROM schema.tablename
WHERE symbol IN ('SPX', 'VIX')
AND NOT (quote_time = time '09:31' AND symbol = 'VIX' AND bid = 0 AND ask = 0);
(If one of the columns can be null then you must consider this in the query, too. E.g. (ask <> 0 OR ask IS NULL).)
You can try below -
SELECT QuoteTime, Symbol, ((Bid+Ask)/2) as MidPoint
FROM schema.tablename
WHERE (QuoteTime, Symbol,Bid,Ask) not in (('09:31:00','VIX',0,0))

How to get subtotals with time datatype in SQL?

I get stuck generating a SQL query. I have a Table in a Firebird DB like the following one:
ID | PROCESS | STEP | TIME
654 | 1 | 1 | 09:08:40
655 | 1 | 2 | 09:09:32
656 | 1 | 3 | 09:10:04
...
670 | 2 | 15 | 09:30:05
671 | 2 | 16 | 09:31:00
and so on.
I need the subtotals for each process group (It's about 7 of these). The table has the "time"-type for the TIME column.I have been trying it with DATEDIFF, but it doesn't work.
You need to use SUM
This question has been answered here.
How to sum up time field in SQL Server
and here.
SUM total time in SQL Server
For more specific Firebird documentation. Read up on the sum function here.
Sum() - Firebird Official Documentation
I think you should use "GROUP BY" to get max time and min time, and to use them in the datediff function. Something like that:
select process, datediff(second, max(time), min(time)) as nb_seconds
from your_table
group by process;

Sql Query for Commissions (Decision?) Table

SQL 2008
I have a commission table that looks like this:
Comm% | ProfitStartRange | ProfitEndRange
0.01 | 0.00 | 100.99
0.02 | 101 | 500.99
0.03 | 501 | 1000.99
etc...
Basically I want create a query that returns the appropriate Comm% based on a value. I would like to do this inline and not in a user defined function if possible as I will be calculating a large set.
SELECT comm from yourtable
where profit BETWEEN yourtable.ProfitStartRange and yourtable.ProfitEndRange