I'm trying to make a query using a calculation. What I'm trying to accomplish is making a query to create a running subtraction instead of addition.
I've tried a few different ways but always seem to end with either an error or with no results showing.
Any and all help would be appreciated thank you.
This is the query:
I want to do running subtraction not running addition, but I can't find any function that will subtract the number.
this is the result that im trying to achive
It could be:
SELECT
ledger.ID,
ledger.[Expense:(type)],
ledger.[Fund allotment],
ledger.Amount,
(Select Amount From ledger
Where ledger.ID = (Select Min(ID) From Ledger))-
Nz((Select Sum(T.Amount) From ledger As T
Where T.ID > (Select Min(ID) From Ledger) And T.ID <= ledger.ID), 0) As
Balance
FROM
ledger
Related
There is a table named STATION.
I want to display half rows of the table.
MYSQL query
SELECT *
FROM STATION
LIMIT (SELECT COUNT(ID) FROM STATION)/2
I tried to perform a query like this but I am getting syntax error.
What is wrong in this query?
How can I perform this query?
One method is to use window functions:
select t.*
from (select t.*,
ntile(2) over (order by id) as tile
from t
) t
where tile = 1;
I have never seen a need of querying exactly half the table.
If you are asking this out of curiosity, that's fair but if there is really a need where you are trying to implement something like this, please revisit the design.
Coming to your question, you can possibly do two things:
Implement a stored procedure and query the count and store in a variable and then pass it on to the actual SELECT query for the LIMIT clause.
From your client code fire 2 different queries - 1 for count and calculate half (non fraction) and then pass it to the limit clause of next select query .
I have a table (invoice) like
InovoiceID Invoice amount
I want to select the invoicenumber, the average invoiceamount, and the difference between actual amount and average invoiceamount for each row. However, when I try to do this,
select invoiceID,
avg(invoiceamount) as Average,
Average - invoiceamount
from invoice
This shows an error that sql command is not complete.
Why is this happening?
PS: I even tried this,
SELECT invoiceid,
(SELECT AVG(invoiceamount) FROM Invoice) AS avg_invamt,
(SELECT AVG(invoiceamount) FROM Invoice) - invoiceamount AS diff
FROM Invoice
But still it shows error.
I am using oracle database express edition.
What you wan't to do without is giving the group group error because you are using a group function without specifing a group by statement. So you can achieve what you want with a sub query or even with the with clause.
In my examples I change a bit the names of the columns.
with a as (
select avg(amount) average
from invoice
)
select id, a.average, a.average - amount as diff
from invoice, a;
OR
select id, a.average, a.average - amount as diff
from invoice,
(select avg(amount) average
from invoice) a;
See it here on sqlfiddle: http://sqlfiddle.com/#!4/0c33e/8
This seems like a query that would benefit windowing functions
However, MySQL doesn't support these kinds of functions.The query below should work.
SELECT invoiceId, avg_inv.amt AS "Average",
avg_inv.amt - invoice.invoiceamount AS "Difference"
FROM invoice,
(SELECT avg(invoiceamount) as "amt" FROM invoice) avg_inv
update: just noticed the question tag changed from mysql to oracle. now you can use windowing functions.
heres a description of their usage in oracle, or you can search the countless SO questions regarding windowing functions.
All - I'm trying to do a basic (in theory) On-Time completion report. I'd like to to list
assigned_to_id | Percent on-time (as a percent - but this is not important now)
I figure I tell MySQL get count of all tasks and a list of all tasks marked close on a date prior to the due date and give me that number... Seems simple?
I'm a sysadmin - not a SQL Developer so excuse the grossness to follow!
I've got
select issues.assigned_to_id, tb1.percent from (
Select
(select count(*) from issues where issues.due_date >= date(issues.closed_on) group by issues.assigned_to_id)/
(select count(*) from issues group by issues.assigned_to_id) as percent
from issues)
as tb1
group by tb1.percent;
It's been mixed up a bit with me trying to solve the multple rows issues so it may be even worse off when I started - but if I could get a list of users with their percentage that would be great!
I'd love to have use something like a "for each" but i know that doesn't exist.
Thanks!
You've got a division operation, e.g (foo) / (bar) and both the numerator and denominator are subqueries, Since you're expecting to take those subqueries and divide their answers, they MUST return a SINGLE value each, e.g. 1 / 2.
The error message indicates that one (or probably both) is returning a multi-value query result, so in effect you're trying to do something like 1,2,3 / 4,5,6, which is not a valid math operation, and you end up with your error message.
Fix the subqueries so they return only a SINGLE value each.
MySQL has equivalent of cross/outer apply which match for this case
SELECT T.*,Data.Value FROM [Table] T OUTER APPLY
you can try to use that.
What you should probably be doing is using an IF statement:
SELECT
assigned_to_id,
SUM(IF(due_date >= date(closed_on), 1, 0))/SUM(1) AS percent
FROM issues
GROUP BY assigned_to_id
ORDER BY percent DESC
Note here I am grouping by assigned_to_id and ordering by percent. This allows you to calculate the percentage for each assigned_to_id group and order those groups by percent.
if we have to exactly rewrite your query, try this.
select issues.assigned_to_id, ((select count(*) from issues where issues.due_date >= date(issues.closed_on) )/
(select count(*) from issues)) as perc from issues group by issues.assigned_to_id;
I think you want something like this, a list of issue ids and percentage done on time.
select distinct issues.assigned_to_id, done_on_time.c / issue_count.c as percent
from issues
join
(select issues.assigned_to_id, count(*) as c
from issues
where issues.due_date >= date(issues.closed_on)
group by issues.assigned_to_id) as done_on_time
on issues.assigned_to_id = done_on_time.assigned_to_id
(select issues.assigned_to_idm, count(*) as c
from issues
group by issues.assigned_to_id) as issue_count
on issues.assigned_to_id = issue_count.assigned_to_id
I have been doing my office work in Excel.and my records have become too much and want to use mysql.i have a view from db it has the columns "date,stockdelivered,sales" i want to add another calculated field know as "stock balance".
i know this is supposed to be done at the client side during data entry.
i have a script that generates php list/report only based on views and tables,it has no option for adding calculation fields, so i would like to make a view in mysql if possible.
in excel i used to do it as follows.
i would like to know if this is possible in mysql.
i don't have much experience with my sql but i imagine first
one must be able to select the previous row.colomn4
then add it to the current row.colomn2 minus current row.colomn3
If there is another way to achieve the same out put please suggest.
Generally speaking, SQL wasn't really intended to yield "running totals" like you desire. Other RDBMS have introduced proprietary extensions to deliver analytic functions which enable calculations of this sort, but MySQL lacks such features.
Instead, one broadly has four options. In no particular order:
Accumulate a running total in your application, as you loop over the resultset;
Alter your schema to keep track of a running total within your database (especially good in situations like this, where new data is only ever appended "to the end");
Group a self-join:
SELECT a.Sale_Date,
SUM(a.Stock_Delivered) AS Stock_Delivered,
SUM(a.Units_Sold) AS Units_Sold,
SUM(b.Stock_Delivered - b.Units_Sold) AS `Stock Balance`
FROM sales_report a
JOIN sales_report b ON b.Sale_Date <= a.Sale_Date
GROUP BY a.Sale_Date
Accumulate the running total in a user variable:
SELECT Sale_Date,
Stock_Delivered,
Units_Sold,
#t := #t + Stock_Delivered - Units_Sold AS `Stock Balance`
FROM sales_report, (SELECT #t:=0) init
ORDER BY Sale_Date
Eggyal has four good solutions. I think the cleanest way to do a running total in MySQL is using a correlated subquery -- it eliminates the group by at the end. So I would add to the list of options:
SELECT sr.Sale_Date, sr.Stock_Delivered, sr.Units_Sold,
(select SUM(sr2.Stock_Delivered) - sum(sr2.Units_Sold)
from sales_report sr2
where sr2.sale_date <= sr.sale_date
) as StockBalance
FROM sales_report sr
ORDER BY Sale_Date
SELECT
sales_report.Stock_Delivered,
sales_report.Units_Sold,
sales_report.Stock_Delivered - sales_report.Units_Sold
FROM
sales_report;
I have the following query I use and it works great:
SELECT * FROM
(
SELECT * FROM `Transactions` ORDER BY DATE DESC
) AS tmpTable
GROUP BY Machine
ORDER BY Machine ASC
What's not great, is when I try to create a view from it. It says that subqueries cannot be used in a view, which is fine - I've searched here and on Google and most people say to break this down into multiple views. Ok.
I created a view that orders by date, and then a view that just uses that view to group by and order by machines - the results however, are not the same. It seems to have taken the date ordering and thrown it out the window.
Any and all help will be appreciated, thanks.
This ended up being the solution, after hours of trying, apparently you can use a subquery on a WHERE but not FROM?
CREATE VIEW something AS
SELECT * FROM Transactions AS t
WHERE Date =
(
SELECT MAX(Date)
FROM Transactions
WHERE Machine = t.Machine
)
You don't need a subquery here. You want to have the latest date in the group of machines, right?
So just do
SELECT
t.*, MAX(date)
FROM Transactions t
GROUP BY Machine
ORDER BY Machine ASC /*this line is obsolete by the way, since in MySQL a group by automatically does sort, when you don't specify another sort column or direction*/
A GROUP BY is used together with a aggregate function (in your case MAX()) anyway.
Alternatively you can also specify multiple columns in the ORDER BY clause.
SELECT
*
FROM
Transactions
GROUP BY Machine
ORDER BY Date DESC, Machine ASC
should give you also what you want to achieve. But using the MAX() function is definitely the better way to go here.
Actually I have never used a GROUP BY without an aggregate function.