I have two table first user table is user's data second table is user_volume table is user cost volume I want one sql query and get user and get monthly sum of cost what is SQL Query?
user_volume
id | user_id | volume | created_at
1 | 1 | 66.00 | 2018-03-03 15:36:45
2 | 1 | 77.00 | 2018-03-03 15:36:21
3 | 1 | 88.00 | 2018-03-03 15:36:11
4 | 2 | 99.00 | 2018-03-03 19:36:15
5 | 2 | 65.05 | 2018-04-04 21:30:07
6 | 2 | 99.00 | 2018-04-04 19:36:15
7 | 2 | 65.05 | 2018-04-04 21:30:07
8 | 1 | 22.00 | 2018-04-04 15:36:45
9 | 1 | 44.00 | 2018-04-04 15:36:21
10 | 1 | 33.00 | 2018-04-04 15:36:11
11 | 2 | 13.00 | 2018-04-04 15:36:45
12 | 2 | 224.00 | 2018-04-04 15:36:21
13 | 2 | 651.00 | 2018-04-04 15:36:11
user
id | name | surname
1 | X | Y
result
user_id | date1(03-2018) | date2(04-2018)
1 | (231) | (99)
2 | (99) | (888)
You seem to want conditional aggregation:
select uv.id as user_id,
sum(case when created_at >= '2018-03-01' and created_at < '2018-04-1'
then volume else 0
end) as volume_month1,
sum(case when created_at >= '2018-04-01' and created_at < '2018-05-1'
then volume else 0
end) as volume_month2
from user_volume uv
group by uv.id
Related
I have user attendance CLOCK IN data like this.
id | userID | created_at
1 | 1 | 2018-06-27 00:15:00
2 | 1 | 2018-06-27 01:43:55
3 | 1 | 2018-06-27 02:43:55
4 | 2 | 2018-06-27 00:15:00
5 | 2 | 2018-06-27 02:43:55
6 | 2 | 2018-06-27 03:43:55
7 | 1 | 2018-06-28 00:55:00
8 | 1 | 2018-06-28 01:43:55
9 | 1 | 2018-06-28 02:43:55
10 | 2 | 2018-06-28 00:00:00
11 | 2 | 2018-06-28 02:43:55
12 | 2 | 2018-06-28 03:43:55
I want a list of dates where user was late to clock in.
Assume company work time is 00:00:00 and
How can I get results like this :
id | userID | created_at
1 | 1 | 2018-06-27 00:15:00
4 | 2 | 2018-06-27 00:15:00
7 | 1 | 2018-06-28 00:55:00
Appreciate any help from you guys.Thanks 🙏🏻
You could try conditionally aggregating by user and date, and then checking to see whether an exact midnight clock in occurred (or did not occur):
SELECT
userID,
MIN(created_at) AS created_at
FROM yourTable
GROUP BY
userID,
DATE(created_at)
HAVING
SUM(CASE WHEN DATE_FORMAT(created_at, '%H:%i:%s') = '00:00:00' THEN 1 ELSE 0 END) = 0;
Demo
I have two tables transaction and detailtransaction, the relation is 1 to N
, here's transaction Table
+-----+----------+--------+---------------------+------------+-------------+---------+---
| ID | TransactionDate | GrandTotal | DownPayment | Status | DatePaid |
+-----+----------+--------+---------------------+------------+-------------+---------+---
| 173 | 2018-01-03 22:05:00 | 26000.00 | 26000.00 | PAID OFF | 2018-01-03 21:05:52 |
| 174 | 2018-01-01 22:06:00 | 26000.00 | 0.00 | PAID OFF | 2018-01-03 22:05:52 |
| 175 | 2018-01-02 22:06:00 | 60000.00 | 10000.00 | - 50000 | 2018-01-03 21:06:55 |
| 176 | 2018-01-03 22:08:00 | 90000.00 | 50000.00 | - 40000 | 2018-01-03 21:08:19 |
| 178 | 2018-01-03 22:34:00 | 70000.00 | 70000.00 | PAID OFF | 2018-01-03 21:35:00 |
| 179 | 2018-01-03 23:13:00 | 52000.00 | 52000.00 | PAID OFF | 2018-01-03 22:13:35 |
+-----+----------+--------+---------------------+------------+-------------+---------+---
and here's transactiondetail table
+----+---------------+-----------+---------------+--------+------+----------+----------+------------+
| ID | TransactionID | ProductID | ServiceID | UserID | Tax | Discount | Quantity | PriceTotal |
+----+---------------+-----------+---------------+--------+------+----------+----------+------------+
| 1 | 173 | NULL | SV031 | 7 | NULL | 0 | 0 | 26000.00 |
| 2 | 174 | NULL | SV032 | 7 | NULL | 0 | 0 | 26000.00 |
| 3 | 175 | NULL | SV033 | 7 | NULL | 0 | 0 | 60000.00 |
| 4 | 176 | 8 | NULL | 7 | NULL | 0 | 1 | 30000.00 |
| 5 | 176 | NULL | SV034 | 7 | NULL | 0 | 0 | 60000.00 |
| 7 | 178 | 5 | NULL | 7 | NULL | 0 | 1 | 70000.00 |
| 8 | 179 | NULL | SV036 | 7 | NULL | 0 | 0 | 26000.00 |
| 9 | 179 | NULL | SV037 | 7 | NULL | 0 | 0 | 26000.00 |
+----+---------------+-----------+---------------+--------+------+----------+----------+------------+
There's 2 things can be made in 1 transaction, buy a product or a service. So there's a ServiceID and ProductID on TransactionDetail's.
on ID 173, someone made transaction of service and paid off
ID 174, someone made transaction 3 days ago and paid it today
ID 175 transaction of service and put Downpayment of 10k
ID 176 transaction of 1 product cost 30k and service cost 60k, downpayment is 50k (minus 40k)
ID 178 buying some product cost 70k
ID 179 2 service and paid off the transaction
The rule is product cant be paid later, only service can
I want to make a report of daily income, how to sum is based on the DatePaid, the result i should get is 26k + 26k + 10k + 50k + 70K + 52k = 230K
i've tried to get SUM by joining the table what i got is it repeating the value, like if theres 2 service in 1 transaction, it sums like its 2 transaction. here's what i tried, i got 336k
SELECT SUM(CASE WHEN Status = 'PAID OFF' THEN GrandTotal ELSE DownPayment END) FROM `transaction` a LEFT JOIN transactiondetail b ON a.ID = b.TransactionID WHERE DatePaid BETWEEN '2018-01-03 00:00:00' AND '2018-01-03 23:59:59'
Also how can I sum only transactiondetail with serviceID so that the product isnt the sum.
Thanks
First of all, if all you need is just the sum of amount, you don't need to join with transaction details. Just the below query will do.
SELECT SUM(CASE WHEN Status = 'PAID OFF' THEN GrandTotal ELSE DownPayment END) FROM transaction WHERE DatePaid BETWEEN '2018-01-03 00:00:00' AND '2018-01-03 23:59:59'
Secondly, what details do you need from transaction details table, do you want to see the amount by product and service grouped.
To get the total sum :
SELECT SUM(CASE WHEN Status = 'PAID OFF' THEN GrandTotal ELSE DownPayment END) FROM `transaction` WHERE DatePaid BETWEEN '2018-01-03 00:00:00' AND '2018-01-03 23:59:59'
removing products can by done by checking if product_id is not null and to get total use sub query as:
SELECT SUM(total) FROM( SELECT SUM(CASE WHEN Status = 'PAID OFF' THEN GrandTotal ELSE DownPayment END) AS total FROM `transaction` a LEFT JOIN transactiondetail b ON a.ID = b.TransactionID WHERE DatePaid BETWEEN '2018-01-03 00:00:00' AND '2018-01-03 23:59:59' AND ProductID IS NULL GROUP BY a.ID ) as t
I have three tables: tbl_job1 , tbl_job2 and tbl_users.
tbl_job1:
ID| DataComplited | Profit | UserID |
===================================
1 | 2017-01-01 | 100 | 1 |
2 | 2017-02-01 | 200 | 1 |
3 | 2017-03-01 | 150 | 1 |
4 | 2017-01-01 | 400 | 2 |
5 | 2017-01-01 | 120 | 1 |
6 | 2017-02-03 | 30 | 1 |
tbl_job2:
ID| DataComplited | Profit | UserID |
===================================
1 | 2017-02-01 | 50 | 1 |
2 | 2017-03-01 | 20 | 1 |
3 | 2017-02-03 | 20 | 1 |
4 | 2017-02-03 | 50 | 1 |
tbl_users:
ID| fullname |
==============
1 | Robert |
2 | Maria |
I want to see:
Fullname | Year | Month | Profit 1 | Profit 2 | Total |
==========================================================
Maria | 2017 |January | 400.00 | |400.00 |
Robert | 2017 |January | 220.00 | |220.00 |
| |February| 230.00 | 120.00 |350.00 |
| | March | 150.00 | 20.00 |170.00 |
But I get:
Fullname | Year | Month | Profit 1 | Profit 2 | Total |
==========================================================
Maria |2017 |January | 400.00 | |400.00 |
Robert |2017 |January | 220.00 | |220.00 |
| |February| 260.00 | 120.00 |380.00 |
| | March | 150.00 | 20.00 |170.00 |
Please see what Robert's got in February.
Sorry about my English, I'm Russian. But I think you can see everything on those tables. Actually I want to see sum from two jobs for every month.
I'm new on MySql, I tried this code:
SELECT
year(tbl_job1.DataComplited) AS `Year`,
DATE_FORMAT(tbl_job1.DataComplited, '%M') AS `Month`,
DATE_FORMAT(tbl_job1.DataComplited, '%m') AS Month_ord,
tbl_users.fullname,
SUM(tbl_job1.Profit) AS Profit_1
SUM(tbl_job2.Profit) AS Profit_2 ,
(SUM(tbl_job1.profit)) + (SUM(COALESCE(tbl_job2.profit, 0))) AS Total
FROM tbl_job1
LEFT OUTER JOIN tbl_job2 ON tbl_job1.DataComplited = tbl_job2.DataComplited
INNER JOIN tbl_users ON tbl_job1.UserID = tbl_users.ID
GROUP BY tbl_users.fullname,
month(tbl_job1.DataComplited),
DATE_FORMAT(`month`, '%m'),year
ORDER BY tbl_users.fullname,
year(tbl_job1.DataComplited),
DATE_FORMAT(tbl_job1.DataComplited, '%M')
Please help me.
thank you, I but I decided by myself.
SELECT
year(a.DataComplited) AS `Year`,
DATE_FORMAT(a.DataComplited, '%M') AS `Month`,
tbl_users.fullname,
SUM(a.Profit) AS Profit_1,
b.Profit AS Profit_2,
SUM(COALESCE(a.Profit, 0)) + COALESCE(b.Profit, 0) as Total
FROM tbl_job1 as a
INNER JOIN tbl_users ON a.UserID = tbl_users.ID
LEFT OUTER JOIN
(
SELECT
DATE_FORMAT(DataComplited, '%M') AS `Month`,
DataComplited,
SUM(COALESCE(tbl_job2.profit, 0)) AS Profit
FROM tbl_job2
GROUP BY month(DataComplited), DATE_FORMAT(`month`, '%m')
) AS b USING (DataComplited)
GROUP BY tbl_users.fullname, month(a.DataComplited), DATE_FORMAT(`month`, '%m'), year
ORDER BY tbl_users.fullname, year(a.DataComplited), DATE_FORMAT(a.DataComplited, '%m')
| ds |
|sales_id| date_issued |
| 1 | 2016-11-30 01:00:00 |
| 2 | 2016-11-30 02:00:00 |
| 3 | 2016-11-30 03:00:00 |
| dsr |
| dsr_id | quantity | date_returned |
| 5 | 1 | 2016-11-30 01:01:00|
| 6 | 1 | 2016-11-30 01:11:00|
| 7 | 3 | 2016-11-30 02:21:00|
| 8 | 1 | 2016-11-30 02:31:00|
| 9 | 2 | 2016-11-30 03:02:00|
How or what query would it be where I could apply this logic
ADD the quantities of dsr WHERE its date_returned is greater than the first date_issued AND less than the following date_issued
that the result would be:
| 2 |
| 4 |
| 2 |
The idea would be something like this:
| dsr |
| dsr_id | quantity | date_returned |
| 5 | 1 | 2016-11-30 01:01:00| --- This 1st and 2nd rows
| 6 | 1 | 2016-11-30 01:11:00| --/ will be added because
the 1st date_issued is
'2016-11-30 01:00:00' >= (the 1st date_returned) < '2016-11-30 02:00:00' which is the following date_issued
| 7 | 3 | 2016-11-30 02:21:00| --- Same idea for this two
| 8 | 1 | 2016-11-30 02:31:00| --/ Since its fits to the condition where this date_returned is just between 2nd & 3rd's date_issued
| 9 | 2 | 2016-11-30 03:02:00|
I know this could be easily done programmatically but I just want to know and learn how to do it in SQL and if it is easier in SQL.
SQL DEMO
SELECT start_date, end_date, SUM(D.quantity)
FROM (
SELECT ds1.`sales_id`,
ds1.`date_issued` start_date,
COALESCE(ds2.`date_issued`, CURRENT_DATE) as end_date
FROM ds as ds1
LEFT JOIN ds as ds2
ON ds1.`sales_id` = ds2.`sales_id` - 1
) R
JOIN dsr D
ON D.`date_returned` >= start_date
AND D.`date_returned` < end_date
GROUP BY start_date, end_date
OUTPUT
I'm building a website for our ball team for the fun of it and keeping track of stats using PHP and SQL for the database. I've learned both by reading the manuals and through forums. I'm working on building a query that will display the current longest hitting streak. I stumbled across a page about detecting runs and streaks and am trying to work with that. I'm really new to all this stuff, so maybe I've structured my tables incorrectly.
Table "games"
+--------+------------+------+
| GameID | Date | Time |
+--------+------------+------+
| 1 | 2015/08/19 | 6:30 |
| 2 | 2015/08/20 | 6:30 |
| 3 | 2015/08/22 | 6:30 |
| 4 | 2015/08/24 | 8:00 |
| 5 | 2015/08/24 | 6:30 |
| 6 | 2015/07/15 | 8:00 |
+--------+------------+------+
Table "player"
+--------+----+---+
| GameID | AB | H |
+--------+----+---+
| 1 | 3 | 1 |
| 2 | 4 | 2 |
| 3 | 2 | 0 |
| 4 | 3 | 0 |
| 5 | 2 | 1 |
| 6 | 3 | 0 |
+--------+----+---+
Code
SELECT games.GameID, GR.H,
(SELECT COUNT(*)
FROM player G
WHERE (CASE WHEN G.H > 0 THEN 1 ELSE 0 END) <> (CASE WHEN GR.H > 0 THEN 1 ELSE 0 END)
AND G.GameID <= GR.GameID) as RunGroup
FROM player GR
INNER JOIN games
ON GR.gameID = games.GameID
ORDER BY Date ASC, Time ASC
Basically in order to correctly get the hit streak right, I need to reorder the GameIDs on the "player" table based on the Date (ASC) and Time (ASC) on the "games" table before executing the RunGroup part of the code. Obviously by adding the ORDER BY, everything gets sorted only after the RunGroup has finished querying and results in incorrect data. I've been stuck here for a few days and now need some help.
The Result I currently get is:
+--------+---+----------+
| GameID | H | RunGroup |
+--------+---+----------+
| 6 | 0 | 3 |
| 1 | 1 | 0 |
| 2 | 2 | 0 |
| 3 | 0 | 2 |
| 5 | 1 | 2 |
| 4 | 0 | 2 |
+--------+---+----------+
This is what I'm trying to achieve:
+--------+---+----------+
| GameID | H | RunGroup |
+--------+---+----------+
| 6 | 0 | 0 |
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 0 | 2 |
| 5 | 1 | 2 |
| 4 | 0 | 3 |
+--------+---+----------+
Thanks
Consider the following:
DROP TABLE IF EXISTS games;
CREATE TABLE games
(game_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,date_played DATETIME NOT NULL
);
INSERT INTO games VALUES
(1,'2015/08/19 18:30:00'),
(2,'2015/08/20 18:30:00'),
(3,'2015/08/22 18:30:00'),
(4,'2015/08/24 20:00:00'),
(5,'2015/08/24 18:30:00'),
(6,'2015/07/15 20:00:00');
DROP TABLE IF EXISTS stats;
CREATE TABLE stats
(player_id INT NOT NULL
,game_id INT NOT NULL
,at_bat INT NOT NULL
,hits INT NOT NULL
,PRIMARY KEY(player_id,game_id)
);
INSERT INTO stats VALUES
(1,1,3,1),
(1,2,4,2),
(1,3,2,0),
(1,4,3,0),
(1,5,2,1),
(1,6,3,0),
(2,1,2,1),
(2,2,3,2),
(2,3,3,0),
(2,4,3,1),
(2,5,2,1),
(2,6,3,0);
SELECT x.*
, SUM(y.at_bat) runningAB
, SUM(y.hits) runningH
, SUM(y.hits)/SUM(y.at_bat) BA
FROM
(
SELECT s.*, g.date_played FROM stats s JOIN games g ON g.game_id = s.game_id
) x
JOIN
(
SELECT s.*, g.date_played FROM stats s JOIN games g ON g.game_id = s.game_id
) y
ON y.player_id = x.player_id
AND y.date_played <= x.date_played
GROUP
BY x.player_id
, x.date_played;
+-----------+---------+--------+------+---------------------+-----------+----------+--------+
| player_id | game_id | at_bat | hits | date_played | runningAB | runningH | BA |
+-----------+---------+--------+------+---------------------+-----------+----------+--------+
| 1 | 6 | 3 | 0 | 2015-07-15 20:00:00 | 3 | 0 | 0.0000 |
| 1 | 1 | 3 | 1 | 2015-08-19 18:30:00 | 6 | 1 | 0.1667 |
| 1 | 2 | 4 | 2 | 2015-08-20 18:30:00 | 10 | 3 | 0.3000 |
| 1 | 3 | 2 | 0 | 2015-08-22 18:30:00 | 12 | 3 | 0.2500 |
| 1 | 5 | 2 | 1 | 2015-08-24 18:30:00 | 14 | 4 | 0.2857 |
| 1 | 4 | 3 | 0 | 2015-08-24 20:00:00 | 17 | 4 | 0.2353 |
| 2 | 6 | 3 | 0 | 2015-07-15 20:00:00 | 3 | 0 | 0.0000 |
| 2 | 1 | 2 | 1 | 2015-08-19 18:30:00 | 5 | 1 | 0.2000 |
| 2 | 2 | 3 | 2 | 2015-08-20 18:30:00 | 8 | 3 | 0.3750 |
| 2 | 3 | 3 | 0 | 2015-08-22 18:30:00 | 11 | 3 | 0.2727 |
| 2 | 5 | 2 | 1 | 2015-08-24 18:30:00 | 13 | 4 | 0.3077 |
| 2 | 4 | 3 | 1 | 2015-08-24 20:00:00 | 16 | 5 | 0.3125 |
+-----------+---------+--------+------+---------------------+-----------+----------+--------+
I rebuilt my database to have only one table to contain the stats from all players. From there i was able to use this query to find my longest current hitting streak for a certain player.
SELECT *
FROM (SELECT (CASE WHEN h > 0 THEN 1 ELSE 0 END) As H, MIN(date_played) as StartDate,
MAX(date_played) as EndDate, COUNT(*) as Games
FROM (SELECT date_played, (CASE WHEN h > 0 THEN 1 ELSE 0 END) as H, (SELECT COUNT(*)
FROM stats G WHERE ((CASE WHEN G.h > 0 THEN 1 ELSE 0 END) <> (CASE WHEN GR.h > 0 THEN 1 ELSE 0 END))
AND G.date_played <= GR.date_played AND player_id = 13) as RunGroup
FROM stats GR
WHERE player_id = 13) A
GROUP BY H, RunGroup
ORDER BY Min(date_played)) A
WHERE H = 1
ORDER BY Games DESC
LIMIT 1