Group by and find amount difference sql same table - mysql

I have table like this below :
And i want the result like : sum the amount group by date and find the difference between the result

If you are using MySQL 8.0 then you can use lag() to achieve expected output.
select
date,
amount,
coalesce((amount - last_val), amount) as diff
from
(
select
date,
amount,
lag(amount) over (order by date) as last_val
from
(
select
date,
sum(amount) as amount
from myTable
group by
date
) subq
) subo
order by
date

Related

How To Display Value by Max Date / Last Date of Year

I need a query to display a value (saldo) following max date / the last date of year, but I have tried but it and it's always showing a value from the first date.
Here is my query:
SELECT saldo, MAX(tgl_lap) FROM laporan GROUP BY DATE_FORMAT(tgl_lap,'%Y','%m') ORDER BY DATE_FORMAT(tgl_lap,'%Y','%m') DESC
my result:
And my expectated result should be only showing values like in the red box below:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY YEAR(tgl_lap) ORDER BY tgl_lap DESC) rn
FROM laporan
)
SELECT *
FROM cte
WHERE rn = 1
select *
From laporan t
where t.tgl_lap =
(
select max(a.tgl_lap)
from laporan a
where year(t.tgl_lap) = year(a.tgl_lap)
)
According to the sample data, considering there would be only one record per date, the sub query will return max date of the year and main query will return complete record of the last or max date of the year.

Average timediff of 2nd and 3rd datetimes for a group

I need to find the average time in days between a customer's second order and third order
I know that I need to use the timestampdiff but am quite at a loss for how to select the second and third dates and need some sort of nest.
SELECT CustomerID,
OrderDate,
diff,
avg(timestampdiff(day, start_date, end_date)) AS average_days
FROM () o3
WHERE date3, date2
ORDER BY CustomerID, OrderDate;
Table
To achieve your desired result, you first need to calculate ROW_NUMBER from your data PARTITION BY CustmerId. Then keep rows only with RowNumber IN (2,3) and then get the DateDiff between two days. The following query will help getting your desired results-
SELECT CustomerID,datediff(MAX(OrderDate),MIN(OrderDate))
FROM
(
SELECT *,
#row_num :=IF(#prev_value = concat_ws('',CsutomerID),#row_num+1,1)AS RowNumber
, #prev_value := concat_ws('',CsutomerID)
FROM your_table A
ORDER BY CustomerID,OrderDate
)B
WHERE B.RowNumber IN (2,3)
GROUP BY CustomerID;

Select from a select result

I have a select SQL query on Mysql that returns a result in the form with two columns:
number date
1 date1
1 date2
2 date3
.
.
How do you i select from the select query and keep only the most recent date for each number.
I have problems working the query result.
You can use your query as a derived table. Since you didn't provide your query, let's use this for example:
SELECT Name, Date
FROM YourQuery
Now take MAX(Date) and GROUP BY Name with your query as the derived table:
SELECT MAX(Date), Name
FROM (
SELECT Name, Date
FROM YourQuery
) a
GROUP BY Name
If you just want to show the number and date, you can do a regular group by on the returned select and it should do the trick:
select
a.number,
max(a.date) from
(select number, date from table_name ) a
group by a.number
If you have other columns that you would like to show on that row with the most recent date, this should do the trick:
select
a.number,
a.lastentrytime,
b.some_other_column
from (
select number,
max(date) recent_date
from table_name group by number) a
inner join table_name b on a.number= b.number and a.recent_date= b.date
;with cte as (
select number, row_number() over(order by date desc) as rn from thistable )
select number from cte where rn=1
You can use this query to get most recent record.

How to Group a table and get results for a row based on the previous rows' data

I have a lookup table that relates dates and people associated with those dates:
id, user_id,date
1,1,2014-11-01
2,2,2014-11-01
3,1,2014-11-02
4,3,2014-11-02
5,1,2014-11-03
I can group these by date(day):
SELECT DATE_FORMAT(
MIN(date),
'%Y/%m/%d 00:00:00 GMT-0'
) AS date,
COUNT(*) as count
FROM user_x_date
GROUP BY ROUND(UNIX_TIMESTAMP(created_at) / 43200)
But, how can get the number of unique users, that have now shown up previously? For instance this would be a valid result:
unique, non-unique, date
2,0,2014-11-01
1,1,2014-11-02
0,1,2014-11-03
Is this possibly without having to rely on a scripting language to keep track of this data?
I think this query will do what you want, at least it seems to work for your limited sample data.
The idea is to use a correlated sub-query to check if the user_id has occurred on a date before the date of the current row and then do some basic arithmetic to determine number of unique/non-unique users for each date.
Please give it a try.
select
sum(u) - sum(n) as "unique",
sum(n) as "non-unique",
date
from (
select
date,
count(user_id) u,
case when exists (
select 1
from Table1 i
where i.user_id = o.user_id
and i.date < o.date
) then 1 else 0
end n
from Table1 o
group by date, user_id
) q
group by date
order by date;
Sample SQL Fiddle
I didn't include the id column in the sample fiddle as it's not needed (or used) to produce the result and won't change anything.
This is the relevant question: "But, how can get the number of unique users, that have now shown up previously?"
Calculate the first time a person shows up, and then use that for the aggregation:
SELECT date, count(*) as FirstVisit
FROM (SELECT user_id, MIN(date) as date
FROM user_x_date
GROUP BY user_id
) x
GROUP BY date;
I would then use this as a subquery for another aggregation:
SELECT v.date, v.NumVisits, COALESCE(fv.FirstVisit, 0) as NumFirstVisit
FROM (SELECT date, count(*) as NumVisits
FROM user_x_date
GROUP BY date
) v LEFT JOIN
(SELECT date, count(*) as FirstVisit
FROM (SELECT user_id, MIN(date) as date
FROM user_x_date
GROUP BY user_id
) x
GROUP BY date
) fv
ON v.date = fv.date;

Calculate average column value per day

I have the following table structure: Value (stores random integer values), Datetime` (stores purchased orders datetimes).
How would I get the average value from all Value rows across a full day?
I'm assuming the query would be something like the following
SELECT count(*) / 1
FROM mytable
WHERE DateTime = date(now(), -1 DAY)
You can GROUP BY the DATE part of DATETIME and use AVG aggregate function to find an average value for each group :
SELECT AVG(`Value`)
, DATE(`Datetime`)
FROM `mytable`
GROUP BY DATE(`Datetime`)
Looks like a simple AVG task:
SELECT `datetime`,AVG(`Value`) as AvgValue
FROM TableName
GROUP BY `datetime`
To find average of a specific day:
SELECT `datetime`,AVG(`Value`) as AvgValue
FROM TableName
WHERE `datetime`=#MyDate
GROUP BY `datetime`
Or Simply:
SELECT AVG(`Value`) as AvgValue
FROM TableName
WHERE `datetime`=#MyDate
Explanation:
AVG is an aggregate function used to find the average of a column. Read more here.
The following query will give you what u want..
SELECT DATE_FORMAT(thedate_field, '%Y-%m-%d') as theday, avg (value)
FROM mytable group by
DATE_FORMAT(thedate_field, '%Y-%m-%d')
Try It its work...
Select AVG(value),convert(nvarchar,DateTime,103) from table group by convert(nvarchar,DateTime,103)