select count in mysql on 2 fields to get aggregated result - mysql

I have a mysql Table.
+----+----------------+-----------+---------------+---------------------+
| id | transaction_id | user_id | book_id | purchase_date |
+----+----------------+-----------+---------------+---------------------+
| 52 | bq4ren25a8w0 | ABC_00002 | xxxx951410361 | 2017-04-25 12:30:18 |
| 66 | j4ax039ilc00 | ABC_00260 | xxxx951410392 | 2017-04-25 12:30:18 |
| 67 | s2a57kp4g000 | ABC_00260 | xxxx951410361 | 2017-06-05 12:28:56 |
| 68 | h4z4h80ts000 | ABC_00260 | xxxx951410415 | 2017-06-07 12:47:24 |
| 69 | 2bt7ipsf9sy3 | ABC_00262 | xxxx951410392 | 2017-06-05 13:25:10 |
| 70 | x0rlwhm00000 | ABC_00264 | xxxx951410392 | 2017-06-09 14:23:08 |
+----+----------------+-----------+---------------+---------------------+
I need a result whic is group by book_id + purchase_date such that
+---------------+---------------------+-------+
| book_id | purchase_date | count |
+---------------+---------------------+-------+
| xxxx951410361 | 2017-04-25 12:30:18 | 10 |
| xxxx951410392 | 2017-06-05 14:27:19 | 12 |
+---------------+---------------------+-------+
I dont have much exposure in mysql, I just tried
Select Count(book_id) as book_id, purchase_date
FROM tbl_name
GROUP BY book_id, purchase_date
Its not working.
Need some help

You can use DATE to group the purchases by days.
SELECT book_id,COUNT(book_id),DATE(purchase_date) AS pdate FROM book_sales GROUP BY book_id,pdate;
If you want to know how many books were sold on a specific day, you can use:
SELECT DATE(purchase_date) AS purchase_date,COUNT(DATE(purchase_date)) AS books FROM book_sales GROUP BY DATE(purchase_date);
http://sqlfiddle.com/#!9/4cde14/6

You can try like this, hope you will get what you need.
SELECT book_id, purchase_date,COUNT(purchase_date) as count
FROM book_sales
GROUP BY purchase_date;

Related

Selecting conditions only when both rows (not either) are met

Parts of the table that I am looking into is as follow:
table: store_inventories
+---------+----------+-------+----------+
| stor_id | title_id | qty | minStock |
+---------+----------+-------+----------+
| 8042 | TC7777 | 630 | 630 |
| 8042 | TH1217 | 0 | 630 |
| 9012 | AK1231 | -100 | 13 |
| 9012 | AK4153 | 5 | 1 |
| 9012 | BU2075 | 39 | 7 |
| 7131 | AW1234 | 10277 | 2055 |
| 7131 | AW5678 | 13150 | 2630 |
| 7131 | BU1032 | 545 | 109 |
| 7131 | BU2075 | 35 | 7 |
How can I select title_id from this table with where conditions that will meet both (not either) stor_ids 9012 and 7131.
The result should be
+----------+
| title_id |
+----------+
| BU2075 |
I tried inner join and using and statement but they either returning wrong result or empty set.
Use WHERE clause to filter the stor_ids and HAVING to count the instances of the rows return in the WHERE clause.
SELECT title_id
FROM store_inventories
WHERE stor_ids IN (9012, 7131) --
GROUP BY title_id
HAVING COUNT(*) = 2
Use DISTINCT if there title can have multiple rows of the same store.
HAVING COUNT(DISTINCT stor_ids) = 2
Here's a Demo.
You can try with a Join of subqueries:
SELECT a.title_id
FROM (select title_id
from store_inventories
where stor_id=9012) a
JOIN (select title_id
from store_inventories
where stor_id=7131) b
ON (a.title_id=b.title_id)

Mysql query not giving the two rows with max numbers

I have query :-
select
CustomerName,
Scenario,
StepNo,
InTransit,
IsAlef,
RunNo,
count(1) as Total
from RequestInfo
group by CustomerName,
Scenario,StepNo,InTransit,
IsAlef,RunNo
order by Total DESC LIMIT 1;
which gives me output :-
+--------------+-------------+--------+-----------+--------+-------+-------+
| CustomerName | Scenario | StepNo | InTransit | IsAlef | RunNo | Total |
+--------------+-------------+--------+-----------+--------+-------+-------+
| MMT | HotelBrowse | 1 | No | No | 2 | 226 |
+--------------+-------------+--------+-----------+--------+-------+-------+
the actual table is :-
+--------------+-------------+--------+-----------+--------+-------+----------+
| CustomerName | Scenario | StepNo | InTransit | IsAlef | RunNo | count(1) |
+--------------+-------------+--------+-----------+--------+-------+----------+
| MMT | HotelBrowse | 1 | No | No | 1 | 206 |
| MMT | HotelBrowse | 1 | No | No | 2 | 226 |
| MMT | HotelBrowse | 1 | No | No | 3 | 206 |
| YATRA | HotelBrowse | 1 | No | No | 1 | 298 |
| YATRA | HotelBrowse | 1 | No | No | 2 | 206 |
| YATRA | HotelBrowse | 1 | No | No | 3 | 147 |
+--------------+-------------+--------+-----------+--------+-------+----------+
but i want output like below:-
+--------------+-------------+--------+-----------+--------+-------+----------+
| CustomerName | Scenario | StepNo | InTransit | IsAlef | RunNo | count(1) |
+--------------+-------------+--------+-----------+--------+-------+----------+
| MMT | HotelBrowse | 1 | No | No | 2 | 226 |
| YATRA | HotelBrowse | 1 | No | No | 1 | 298 |
+--------------+-------------+--------+-----------+--------+-------+----------+
The idea is to get the rows with max count numbers of the last column "Total".
Check This.
select R1.* from RequestInfo R1
inner join
(
select CustomerName,MAX( `count(1)`) `count(1)`
from RequestInfo
group by CustomerName
)R2 on R1.CustomerName=R2.CustomerName and R1.`count(1)`=R2.`count(1)`
Demo : sqlfiddle here
Please try below query
select a.* from RequestInfo a,
(select CustomerName,max(Total) as total from RequestInfo group by CustomerName ) b
where a.customername=b.customername
and a.total=b.total;
Just set your 'TOTAL DESC LIMIT' as '2'
SELECT CustomerName, Scenario,StepNo,InTransit,IsAlef,RunNo, count(1) AS
Total FROM RequestInfo GROUP BY
CustomerName, Scenario,StepNo,InTransit,IsAlef,RunNo ORDER BY Total DESC LIMIT 2;
error because count is reserved keyword in mysql so you can write between count(1) not only count without acute
your query like this
select CustomerName,Scenario,StepNo,InTransit,IsAlef,RunNo,`count(1)` as Total from customer group by CustomerName;
check here

How do I select the population of a User table as an increasing value by DATE?

Consider this excerpt of our Users table:
+-------------+---------------------+---------------------+
| id | last_login | created |
+-------------+---------------------+---------------------+
| 14551578822 | 2014-02-22 17:38:39 | 2013-03-26 23:30:50 |
| 18442388426 | 0000-00-00 00:00:00 | 2013-11-07 15:51:11 |
| 49983341634 | 2014-03-06 22:28:47 | 2013-03-23 16:00:05 |
| 9527246957 | 2014-01-17 02:37:53 | 2013-05-14 02:14:49 |
| 58667409337 | 2014-03-08 06:54:01 | 2013-05-15 01:52:23 |
| 1907780002 | 2014-03-01 03:24:04 | 2013-05-01 07:57:56 |
| 65319490251 | 2014-03-19 05:49:41 | 2013-03-23 08:53:43 |
| 23896465717 | 0000-00-00 00:00:00 | 2012-10-21 10:52:23 |
| 19147401900 | 0000-00-00 00:00:00 | 2013-05-01 17:43:28 |
| 28598429318 | 0000-00-00 00:00:00 | 2014-03-14 14:44:15 |
+-------------+---------------------+---------------------+
We have many, many users - and we would like to generate a report that will display the total number of users we have as the date increases. We would like output similar to this:
+---------+---------------+
| DATE | User Count |
+---------+---------------+
| 2012-08 | 122 |
| 2012-09 | 1746 |
| 2012-10 | 3847 |
| 2012-11 | 5826 |
...
| 2014-03 | 472647 |
| 2014-04 | 497286 |
+---------+---------------+
There must be some way to do it without subselects and all kinds of messiness like that. I have a table already that displays the number of joins per period by the following query:
SELECT DATE(users.created) as JOIN_DATE , COUNT(users.id) AS JOIN_COUNT from users
WHERE users.created > '2012-07-01 00:00:00'
GROUP BY JOIN_DATE
ORDER BY JOIN_DATE ASC
Just wondered if there was a way to do it something like that.
Thanks!
You can use a variable to sum up the population foreach iteration
SELECT t.date ,
#population := #population+t.per_time population
FROM (
SELECT
DATE_FORMAT(`last_login` ,'%Y-%m') `date`,
COUNT(*) per_time
FROM Table1
WHERE created > '2012-07-01 00:00:00'
GROUP BY `date` ) t ,
(SELECT #population:=0) p
Fiddle Demo

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)

What does group by do exactly ?

From an example taken from here , I'm trying to understand what does GROUP BY do exactly :
Given this employee table :
+-------+----------+--------+------------+
| Empid | Empname | Salary | DOB |
+-------+----------+--------+------------+
| 1 | Habib | 2014 | 2004-12-02 |
| 2 | Karan | 4021 | 2003-04-11 |
| 3 | Samia | 22 | 2008-02-23 |
| 4 | Hui Ling | 25 | 2008-10-15 |
| 5 | Yumie | 29 | 1999-01-26 |
+-------+----------+--------+------------+
After executing mysql> select * from employee group by empname;
We get :
+-------+----------+--------+------------+
| Empid | Empname | Salary | DOB |
+-------+----------+--------+------------+
| 1 | Habib | 2014 | 2004-12-02 |
| 4 | Hui Ling | 25 | 2008-10-15 |
| 2 | Karan | 4021 | 2003-04-11 |
| 3 | Samia | 22 | 2008-02-23 |
| 5 | Yumie | 29 | 1999-01-26 |
+-------+----------+--------+------------+
So , does that mean that GROUP BY just sorts a table by key ?
Thanks
GROUP BY enables summaries. Specifically, it controls the use of summary functions like COUNT(), SUM(), AVG(), MIN(), MAX() etc. There isn't much to summarize in your example.
But, suppose you had a Deptname column. Then you could issue this query and get the average salary by Deptname.
SELECT AVG(Salary) Average,
Deptname
FROM Employee
GROUP BY Deptname
ORDER BY Deptname
If you want your result set put in a certain order, use ORDER BY.