SQL: Counting and grouping rows - mysql

id | userid | exerciseid | date | time | weight | distance | reps
1 | 24 | 1 | 2013-09-28 00:00:00 | 2321 | 231 | 121 | NULL
2 | 24 | 24 | 2013-09-28 00:00:00 | 2321 | 231 | 121 | NULL
3 | 24 | 1 | 2013-09-28 00:00:00 | 2321 | 231 | 121 | NULL
4 | 24 | 1 | 2000-00-00 00:00:00 | NULL | 100 | NULL | 2
5 | 24 | 1 | 2013-09-28 00:00:00 | 2321 | 231 | 121 | NULL
Rows 1, 3, and 5 are the same. I want to do a count that groups them together, whilst also adding a column with the count value.
SELECT id, userid, exerciseid, date, time, weight, distance, reps
FROM `exercises`
WHERE `userid` = 1 AND `date` < now()
So I want this to return something similar too:
id | userid | exerciseid | date | time | weight | distance | reps | count
1 | 24 | 1 | 2013-09-28 00:00:00 | 2321 | 231 | 121 | NULL | 3
4 | 24 | 1 | 2000-00-00 00:00:00 | NULL | 100 | NULL | 2 | NULL

Try this
SELECT id, userid, exerciseid, date, time, weight, distance, reps,
count(*) as count
FROM `exercises`
WHERE userid = 1 AND date < now()
GROUP BY id, userid, exerciseid, date, time, weight, distance, reps

Try this :
SELECT Count(*) As CountM, id, userid, exerciseid, date, time, weight, distance, reps
FROM `exercises`
WHERE `userid` = 1 AND `date` < now()
Group by id, userid, exerciseid, date, time, weight, distance, reps

Related

How to SUM values for DISTINCT values of another column and GROUP BY date?

How can we SUM amount for each activity only on same date and output a row for each date? This query is not working.
SELECT SUM(amount), type, date FROM table GROUP BY DISTINCT date;
Table
+----+------------+-----------+---------+
| id | date | activity | amount |
+----+------------+-----------+---------+
| 1 | 2017-12-21 | Shopping | 200 |
| 2 | 2017-12-21 | Gift | 240 |
| 3 | 2017-12-23 | Give Away | 40 |
| 4 | 2017-12-24 | Shopping | 150 |
| 5 | 2017-12-25 | Give Away | 120 |
| 6 | 2017-12-25 | Shopping | 50 |
| 7 | 2017-12-25 | Shopping | 500 |
+----+------------+-----------+---------+
Required Result
+------------+-----------+------+-----------+
| date | Shopping | Gift | Give Away |
+------------+-----------+------+-----------+
| 2017-12-21 | 200 | 240 | |
| 2017-12-23 | | | 40 |
| 2017-12-24 | 150 | | |
| 2017-12-25 | 550 | | 120 |
+------------+-----------+------+-----------+
Use:
select `date`,
sum(if (activity='Shopping', amount, null)) as 'Shopping',
sum(if (activity='Gift', amount, null)) as 'Gift',
sum(if (activity='Give Away', amount, null)) as 'Give Away'
from table
group by `date`
You can try this. It returns exact result that you want
SELECT t.date,
SUM(t.shopping_amount) AS shopping,
SUM(t.gift_amount) AS gift,
SUM(t.give_away_amount) AS give_away
FROM
(
SELECT p.`date`, p.`activity`, p.`amount` AS shopping_amount,
0 AS gift_amount, 0 AS give_away_amount
FROM products p
WHERE p.`activity` = 'Shopping'
UNION
SELECT p.`date`, p.`activity`, 0 AS shopping_amount,
p.amount AS gift_amount, 0 AS give_away_amount
FROM products p
WHERE p.`activity` = 'Gift'
UNION
SELECT p.`date`, p.`activity`, 0 AS shopping_amount,
0 AS gift_amount, p.amount AS give_away_amount
FROM products p
WHERE p.`activity` = 'Give Away'
) t
GROUP BY t.date
Hmmm, you can't pivot your results into column headers unless you know all possible values as demonstrated by slaasko but you can get the results using sql into a form which can be pivoted using your display tool ( e.g. slice of BI tool).
SELECT SUM(amount), activity, date FROM table GROUP BY date, activity;

SQL: Get Sum of Column AND Last Entry

I have two tables that I am joining together:
SELECT
type,
name,
SUM(value) as total_value,
target,
target_month,
operator,
SUM(value_1) as total_value1,
AVG(average_of_total) as average
FROM
(SELECT
stats.`type`, stat_type.`target`, stat_type.`target_month`, stat_type.`operator`, stats.`monthly`, stats.`value`, stats.`value_1`, stats.`created_at`, `name`, stats.`average_of_total`
FROM
tefl_stats_customer as stats
JOIN
tefl_stats_customer_type as stat_type
ON
stats.`type` = stat_type.`id`) AS all_data
WHERE
created_at BETWEEN '20147-05-09 00:00:00' AND '2017-05-10 23:00:00' AND monthly = 0
GROUP BY `type`
at the moment this is returning:
| type | Name | total_value | target | target_month | operator | total_value1 | average |
| 12 | English | 3,378 | 400 | 8000 | <= | 0 | 0 |
| 9 | Chinese | 314 | 24 | 0 | = | 426 | 2.03698 |
| 1 | Japanese | 374 | 5 | 0 | < | 78 | 6.5 |
At the moment, as you can see I am getting the SUM() of 'value' as total_value.
Value is found in the table: tefl_stats_customer. This table has thousand of rows.
How can I get the last row in the above query and to have that outputted as last_entry?

Find Latest record by date for each distinct column value

I am working with a dataset with a similar format to the following:
Table: Account
*-----------*----------*-------------*
| id | amount | date |
*-----------*----------*-------------*
| 1 | 100 | 01/01/2016 |
| 2 | 100 | 01/02/2016 |
| 3 | 100 | 01/03/2016 |
| 4 | 200 | 01/04/2016 |
| 5 | 200 | 01/05/2016 |
| 6 | 200 | 01/06/2016 |
| 7 | 300 | 01/07/2016 |
| 8 | 300 | 01/08/2016 |
| 9 | 300 | 01/09/2016 |
| 10 | 400 | 01/10/2016 |
*-----------*----------*-------------*
I need a query to return that returns the most recent record for every distinct value in the table. So, the above table would return
*-----------*----------*-------------*
| id | amount | date |
*-----------*----------*-------------*
| 3 | 100 | 01/03/2016 |
| 6 | 200 | 01/06/2016 |
| 9 | 300 | 01/09/2016 |
| 10 | 400 | 01/10/2016 |
*-----------*----------*-------------*
I am still new to subqueries but I tried the following
SELECT a.id, a.amount, a.date FROM account a WHERE a.date IN (SELECT MAX(date) FROM account)
However this only return the latest date. How can I get the latest date for every distinct value in the amount column.
If you only need amount:
SELECT amount, MAX(date) from myTable group by amount
If you need more data:
SELECT * from myTable where (amount, date) IN (
SELECT amount, MAX(date) as date from table group by amount
)
Or maybe this will run faster:
SELECT * from myTable A WHERE NOT EXISTS (
SELECT 1
FROM myTable B
WHERE A.date < B.date
AND A.amount = B.amount
)

MySQL Return Count for All Dates in Month, Including Those w/ Zero Results

I have a MySQL table that looks like this:
+--------+------------+------------------+
| id | account_id | posted_at |
+--------+------------+------------------+
| 1 | 1 | 2013-10-05 23:09 |
| 2 | 1 | 2013-10-07 14:24 |
| 3 | 1 | 2013-10-07 01:17 |
| 4 | 1 | 2013-10-09 06:58 |
+--------+------------+------------------+
For a particular account_id (in this case 1), I want to return this (for dates in the current month):
+--------+------------+
| count | date |
+--------+------------+
| 0 | 2013-10-01 |
| 0 | 2013-10-02 |
| 0 | 2013-10-03 |
| 0 | 2013-10-04 |
| 1 | 2013-10-05 |
| 0 | 2013-10-06 |
| 2 | 2013-10-07 |
| 0 | 2013-10-08 |
| 1 | 2013-10-09 |
+--------+------------+
I have a SQL query that returns the COUNTS for each date within this month.
SELECT
DATE(posted_at) AS formatted_date,
COUNT(id) AS count
FROM entries
WHERE account_id = 1
AND MONTH(DATE(posted_at)) = MONTH(NOW())
GROUP BY formatted_date
ORDER BY formatted_date ASC
It's just returning this:
+--------+------------+
| count | date |
+--------+------------+
| 1 | 2013-10-05 |
| 2 | 2013-10-07 |
| 1 | 2013-10-09 |
+--------+------------+
Of course, COUNT doesn't return anything for dates that have no data. I want the result to have a zero for dates with no data.
I've read that you should create a join table of all possible dates. Is this the only way?
You can try something like this
Declare #INT DATETIME = null
SELECT COUNT( CASE WHEN #INT IS NOT NULL THEN #INT ELSE NULL END)
Im not to sure about mysql but in sql server it would be something like this...
SELECT
DATE(posted_at) AS formatted_date,
COUNT( CASE WHEN IS NOT NULL THEN posted_at ELSE NULL END ) AS [count]
FROM entries
WHERE account_id = 1
AND MONTH(DATE(posted_at)) = MONTH(NOW())
GROUP BY formatted_date
ORDER BY formatted_date ASC

MySQL Select one row with unique attribute value

I'm building a stock keeping system and decided to store each product's balance (everytime it's updated) into the following table:
+------------+--------------+---------+------+
| Product_id | Warehouse_id | Balance | Date |
+------------+--------------+---------+------+
Example:
Staff adds 10 pieces to product_id 123 in warehouse_id 5
+------------+--------------+---------+-------------+
| Product_id | Warehouse_id | Balance | Date |
+------------+--------------+---------+-------------+
| 123 | 5 | 10 | 2013-09-16 |
+------------+--------------+---------+-------------+
Staff then adds 3 pieces to product 234 in warehouse_id 5, and
5 pieces to 123 in warehouse_id 5,
+------------+--------------+---------+-------------+
| Product_id | Warehouse_id | Balance | Date |
+------------+--------------+---------+-------------+
| 123 | 5 | 10 | 2013-09-16 |
| 234 | 5 | 3 | 2013-09-18 |
| 123 | 5 | 15 | 2013-09-21 |
+------------+--------------+---------+-------------+
*Notice the date column
Now let me add a few more rows
+------------+--------------+---------+-------------+
| Product_id | Warehouse_id | Balance | Date |
+------------+--------------+---------+-------------+
| 123 | 5 | 10 | 2013-09-16 |
| 234 | 5 | 3 | 2013-09-18 |
| 123 | 5 | 15 | 2013-09-21 |
| 123 | 5 | 18 | 2013-09-24 |
| 234 | 5 | 10 | 2013-09-26 |
| 123 | 5 | 22 | 2013-09-29 |
+------------+--------------+---------+-------------+
How do i run a query that would get me all products' balances as at 25th of September 2013?
That means i need the following result:
+------------+--------------+---------+-------------+
| Product_id | Warehouse_id | Balance | Date |
+------------+--------------+---------+-------------+
| 234 | 5 | 3 | 2013-09-18 |
| 123 | 5 | 18 | 2013-09-24 |
+------------+--------------+---------+-------------+
In short I need the latest row (by date), per product_id.
Any help would be greatly appreciated!
Assuming that products' balances are being maintained per warehouse you can do it like this
SELECT t.product_id, t.warehouse_id, t.balance, t.date
FROM table1 t JOIN
(
SELECT warehouse_id, product_id, MAX(date) date
FROM table1
WHERE date <= '2013-09-25'
GROUP BY warehouse_id, product_id
) q
ON t.warehouse_id = q.warehouse_id
AND t.product_id = q.product_id
AND t.date = q.date
Output:
| PRODUCT_ID | WAREHOUSE_ID | BALANCE | DATE |
|------------|--------------|---------|------------|
| 234 | 5 | 3 | 2013-09-18 |
| 123 | 5 | 18 | 2013-09-24 |
Here is SQLFiddle demo
SELECT *
FROM TABLE
WHERE (PRODUCT_ID, DATE) IN
(SELECT PRODUCT_ID, MAX(DATE) FROM TABLE
WHERE DATE <= '2013-09-25'
GROUP BY PRODUCT_ID )
Query:
SQLFIDDLEExample
SELECT *
FROM table1 t
WHERE t.`Date` = (SELECT MAX(t2.`Date`)
FROM Table1 t2
WHERE t2.`Date` <= '2013-09-25'
AND t2.product_id = t.product_id)