I have a table
DAY 1
ID
amount
DATE
1
10
12-02-2020
2
15
12-02-2020
3
20
12-02-2020
4
25
12-02-2020
I did a sum of the amount on day one which turns out to be 70
Now next day I have few more rows where the amount is UPDATED an APPENDED
New tables looks like this
DAY 2
ID
amount
DATE
1
10
12-02-2020
2
20
13-02-2020
3
20
12-02-2020
4
25
12-02-2020
5
30
13-02-2020
6
35
14-02-2020
Now if you see the ID 2 has new updates amount which is 20 earlier 15
and it has new data from dates 13 and 14 on ID 5 and 6
Can I just run a query where it will only process the changed data and add it to the
previous sum
so like 30+35+5(as only 5 increased from the last value)
total = 70
Mainly to process changed data
This will very much depend on how the historical data will be provided.
This example requires additional Day column in the historical data table AND that you're using a MySQL version that supports LAG() (e.g. MySQL v8+ OR MariaDB 10.3+). Let's assume that it's possible for the historical data table to be like this:
ID
Amount
Date
Day
1
10
2020-02-12
1
2
15
2020-02-12
1
3
20
2020-02-12
1
4
25
2020-02-12
1
1
10
2020-02-12
2
2
20
2020-02-13
2
3
20
2020-02-12
2
4
25
2020-02-12
2
5
30
2020-02-13
2
6
35
2020-02-14
2
.. then maybe a query like this:
SELECT Day,
SUM(amount) AS Total,
SUM(amount)-LAG(SUM(amount)) OVER (ORDER BY Day) AS diff
FROM historical_data
GROUP BY Day
ORDER BY Day;
OR (in for MariaDB):
SELECT Day, Total,
Total-LAG(Total) OVER (ORDER BY Day) AS Diff
FROM
(SELECT Day,
SUM(amount) AS Total
FROM historical_data
GROUP BY Day) A;
This will return result like:
Day
Total
diff
1
70
2
140
70
I was following an example from this site on how to use LAG() to get the row data value above it an using them to subtract the SUM(amount) value for that day.
Here's a demo fiddle of the experiment.
Related
I'm facing an issue while creating a sql query where I want transaction details which is older than 2 months. Can someone help me with this.
Basically, I have two table one transaction tables and one customer table.
For each customer there is record of transactions in transaction table. So, now I want a query which can retrieve all the customer_ids which didn't have any transactions in past 2 months.
Customers
id
name
1
Google
2
Facebook
3
Hooli
4
Yahoo!
Transaction
id
transaction_date
customer_id
1
2022-04-10
1
2
2022-04-05
1
3
2022-03-09
1
4
2022-03-24
1
5
2022-02-23
2
6
2022-02-22
2
7
2022-02-21
2
8
2022-03-24
2
9
2022-03-24
3
10
2022-01-23
4
11
2022-01-22
4
12
2022-01-21
4
Output
Customer_id=4(since it do not have any transactions in past 2 months)
Thank you
You can use the MySQL INTERVAL in your select query. Like this:
SELECT customer_id FROM `transaction`
GROUP BY customer_id
HAVING (CURDATE() - INTERVAL 2 MONTH) > MAX(transaction_date);
OUTPUT
customer_id
-------------
4
This query is based on the MAX(transaction_date) of the customer.
I have a table that that is being joined by another table that looks like this:
Id Score Total
1 10 30
1 7 30
1 13 30
2 14 27
2 10 27
2 3 27
I want to be able to display this data like this in SSRS:
Id 1 2 3 Total
1 10 7 13 30
2 14 10 3 27
Can this be done and how?
You can do this by using a matrix.
You can add a row identifier for each id in your dataset (assuming you can modify the dataset, as you joined 2 tables). Below code is for SQL Server (T-SQL).
Select Id, Score, row_number() over (partition by id order by score) ident
from table
Output:
Id Score Ident
1 10 1
1 7 2
1 13 3
2 14 1
2 10 2
2 3 3
No need of the Total field, you can add it in matrix (Right Click on ColumnGroup>Add Total>After).
Use the above query in Matrix as shown below.
Suppose i have a table like this
id user_id activity_id start_time duration
1 1 1 2015-12-02 12:24:22 00:17:25
1 1 2 2015-12-02 12:25:22 00:17:25
1 1 3 2015-12-02 12:26:22 00:17:25
1 1 4 2015-12-02 12:26:22 00:17:25
1 1 4 2015-12-02 12:27:22 00:17:25
1 1 4 2015-12-02 12:29:22 00:17:25
1 1 4 2015-12-02 12:33:22 00:17:25
Now,suppose i need a query something like which count the number within 3 minute from each other-for example
like
12:24:22 is 4 it get count 24 25 and 26
12:25:22 is 2 it get count 25 and 24
12:25:22 is 4 it get count 25 26 and 27
12:26:22 is 4 it get count 24 25 and 26
12:26:22 is 3 it get count 26 and 27 ie it get count of near by 3 minute.
(but in Actually, i will have interval time is 10 minute).
i need to count nearby every minute within interval from each.i see some solution like
MySQL GROUP BY DateTime +/- 3 seconds. But i dont get how actually i can apply it in my suation.Can you please give me some hints to how to works with this.
Thanks in advance.
How about something like:
SELECT t1.start_time, COUNT(*) FROM table AS t1
CROSS JOIN table AS t2
WHERE ABS(TIMESTAMPDIFF(MINUTE, t1.start_time, t2.start_time)) < 10
GROUP BY t1.start_time
Note this would give matches with start_times within 10 minutes BOTH sides of the stated time.
SELECT a.*, COUNT(a.start_time) AS TOT
FROM `your_table`AS a
INNER JOIN `your_table` AS b
WHERE ABS(TIME_TO_SEC(a.start_time) - TIME_TO_SEC(b.start_time)) < 180
GROUP BY a.start_time
Where 180 = 3 minutes(180sec)
#Jonathan Twite answer works too
I am pretty new to mySQL and I have had a hard time over the past 2 days trying to get this to work. I do not know if the title is correct in relation on what I am trying to fix, but if it is not, please correct me.
Here is the deal:
I have 4 columns... id, number, package_id, and date.
id - Increments every time a new row is inserted
number - Just a 2 digit number
package_id - ID of package
date - date and time row was inserted
Here is what an example table looks like: (I omitted the time from the date)
id number package_id date
--- ------ ---------- ----
1 12 20 08-01-2013
2 12 21 08-01-2013
3 12 20 08-01-2013
4 45 20 08-02-2013
5 45 22 08-02-2013
6 45 22 08-03-2013
7 12 20 08-03-2013
8 70 25 08-03-2013
9 70 26 08-03-2013
10 70 25 08-03-2013
Not only am I trying to select distinct for number and group by date. I am also trying to make sure it does it for each unique value in the package_id column.
To better explain, this is what i want the output to be like when I SELECT *:
id number package_id date
--- ------ ---------- ----
1 12 20 08-01-2013
2 12 21 08-01-2013
4 45 20 08-02-2013
5 45 22 08-02-2013
6 45 22 08-03-2013
7 12 20 08-03-2013
8 70 25 08-03-2013
9 70 26 08-03-2013
As you can see only row 3 and 10 did not get selected because of the same number and package_id together within the same day.
How can I accomplish this?
Is this what you are looking for:
SELECT MIN(id), number, package_id, date
FROM MyTable
GROUP by number, package_id, date
It certainly satisfies your expected result set.
i have a database with workers, stations and session. A session describes at which time which worker has been on which station. I managed to build a query that gives me the duration of the overlap of each session.
SELECT
sA.station_id,
sA.worker_id AS worker1,
sB.worker_id AS worker2,
SEC_TO_TIME(
TIME_TO_SEC(LEAST(sA.end,sB.end)) - TIME_TO_SEC(GREATEST(sA.start,sB.start))
) AS overlap
FROM
`sessions` AS sA,
`sessions` AS sB
WHERE
sA.station_id = sb.station_id
AND
sA.station_id = 6
AND (
sA.start BETWEEN sB.start AND sB.end
OR
sA.end BETWEEN sB.start AND sB.end
)
With this query i get an result like this
station_id worker1 worker2 overlap
6 1 1 09:00:00
6 2 1 02:30:00
6 5 1 00:00:00
6 1 1 09:00:00
6 2 1 01:30:00
6 3 1 09:00:00
...
6 12 3 02:00:00
6 14 3 01:00:00
6 17 3 02:00:00
...
What i would like now is to sum up the overlap for every combination of worker1 and worker2 to get the overall overlap duration.
I tried different ways of using SUM() and GROUP BY but i never got the wanted result.
SELECT
...
SEC_TO_TIME(
**SUM**(TIME_TO_SEC(LEAST(sA.end,sB.end)) - TIME_TO_SEC(GREATEST(sA.start,sB.start)))
) AS overlap
...
#has as result
station_id worker1 worker2 overlap
6 1 1 838:59:59
#in combination with
GROUP BY
worker1
#i get
station_id worker1 worker2 overlap
6 1 1 532:30:00
6 2 1 -33:00:00
6 3 1 270:30:00
6 5 1 598:30:00
6 6 1 542:00:00
6 7 1 508:00:00
6 8 5 53:00:00
6 9 1 54:30:00
6 10 1 310:00:00
6 11 1 -108:00:00
6 12 1 593:30:00
6 14 1 97:30:00
6 15 1 -53:30:00
6 17 1 293:30:00
the last result is close but i am still missing a lot of combinations. I also dont understand why the combination 8 - 5 is displayed.
thanks for ur help (and time to read)
aaargh, sorry for my stupidity, the solution was fairly simple
....
SUM(((UNIX_TIMESTAMP(LEAST(sA.end,sB.end))-UNIX_TIMESTAMP(GREATEST(sA.start,sB.start)))/3600))
...
GROUP BY station_id, worker1, worker2
ORDER BY worker1, worker2
i switched to using timestamps and transforming it to hours by /3600 because my former used approach with TIME_TO_SEC and SEC_TO_TIME only used the TIME part of the DATETIME field and thereby produced some wrong numbers. With MySQL 5.5 i could use TO_SECONDS but unfortunately my server is still runing 5.1.