I am new here so if its not fixed topic please fix me.
I have this table:
id | uid | month | year
-----------------------
1 | 5 | 12 | 2018
2 | 5 | 12 | 2018
3 | 9 | 12 | 2018
4 | 3 | 01 | 2019
I want to count how much times for each uid the month and year values equal to - month=12 AND year=2018
for example I want to get response like that:
uid=5 - count = 2
uid=9 - count = 1
How its possible?
With group by uid:
select uid, count(*) as counter
from table
where month = 12 and year = 2018
group by uid
You can use conditional aggregation:
select uid,
sum(case when year = 2018 and month = 12 then 1 else 0 end) as cnt
from t
group by uid;
This will include uids with a count of 0. If you just want uids where the count is greater than 0, use a where clause:
select uid, count(*)
from t
where year = 2018 and month = 12
group by uid;
Select uid, count(*) from table where year=2018 and month=12 group by uid
Related
This is sample data in my table
id_item | qty | t_in | t_out | created_at
1 5 1 0 2018-07-05 10:41:00
1 5 1 0 2018-08-03 10:41:00
1 5 0 1 2018-08-05 10:41:00
1 5 1 0 2018-09-05 10:41:00
1 5 1 0 2018-09-20 10:41:00
1 5 0 1 2018-10-31 10:41:00
My expected result will be
id_item | qty | year | month
1 5 2018 07
1 5 2018 08
1 15 2018 09
1 10 2018 10
What i have tried it works, but not desired output when want to group by montly
$date = '2018-10-31'
$test = Model::whereDate('created_at','<=',$date)->select(DB::raw('(SUM(CASE T_IN WHEN 1 THEN qty ELSE qty * - 1 END)) as total'))->groupBy('id_item')->get();
Raw queries to get the quantity for one month
Select id_item,
(SUM(CASE T_IN WHEN 1 THEN qty ELSE qty * - 1 END)) as total
from transactions
where DATE(created_at) <= 2018-10-31
group by id_item
Worst case
$last_day_of_month = [//list of last day of each month]
//then using loop to get qty of each month refer to the raw queries above
From the query above, i only able to get one line of record. I also tried to group by month and year but incorrect result caused of the date condition. How can i include multiple <= $date condition and group it accordingly to get desired output?
Any idea or is that possible to make it? Thanks.
It is a Rolling Sum problem. In newer versions of Mariadb/MySQL, it can be solved using Window Functions with Frames. However, you don't have that available.
We can rather solve this using user-defined variables. In a Derived table, we first determine the total change in qty for a month. Then, we use this result-set to calculate "final qty" at the end of a month, by adding up the previous month (row)'s qty with current month (row)'s qty_change.
I have also extended the query to consider the cases when there are more than one id_item values.
Try the following Raw query:
SELECT
#roll_qty := CASE WHEN #id_itm = dt.id_item
THEN #roll_qty + dt.qty_change
ELSE dt.qty_change
END AS qty,
#id_itm := dt.id_item AS id_item,
dt.year,
dt.month
FROM
(
SELECT
t.id_item,
SUM(t.qty * t.t_in - t.qty * t.t_out) AS qty_change,
YEAR(t.created_at) AS `year`,
LPAD(MONTH(t.created_at), 2, '0') AS `month`
FROM your_table AS t
GROUP BY t.id_item, `year`, `month`
ORDER BY t.id_item, `year`, `month`
) AS dt
CROSS JOIN (SELECT #roll_qty := 0,
#id_itm := 0
) AS user_init_vars;
| id_item | year | month | qty |
| ------- | ---- | ----- | --- |
| 1 | 2018 | 07 | 5 |
| 1 | 2018 | 08 | 5 |
| 1 | 2018 | 09 | 15 |
| 1 | 2018 | 10 | 10 |
View on DB Fiddle
If you are going to use variables, you need to do it correctly. MySQL does not guarantee the order of evaluation of expressions in a SELECT. So, a variable should not be assigned in one expression and then used in another.
This makes for complicated expressions, but it is possible:
select yyyy, mm, total,
(#t := if(#ym = concat_ws('-', yyyy, mm), #t + total,
#ym := concat_ws('-', yyyy, mm), total
)
) as running_total
from (select year(created_at) as yyyy, month(created_at) as mm,
id_item,
sum(case T_IN when 1 then qty else - qty end) as total
from transactions
where created_at < '2018-11-01'
group by id_item
order by id_item, min(created_at)
) i cross join
(select #ym := '', #n := 0);
Table example
id | name | value | date
--------------------------------------------
1 | abc | 20 | 2018-01-26
1 | abc | 24 | 2018-01-27
1 | abc | 25 | 2018-01-28
1 | abc | 30 | 2018-01-29
I know how to fetch data from 28th Jan or today. But I need some way to show values of two dates in two columns. Is it possible in one mysql query?
Like this
name | value_today | value_pre
---------------------------------------
abc | 30 | 25
You can achieve this using the case. This query returns the today's value and previous date value:
SELECT
id, name,
Sum(Case When date = CURDATE()
Then value Else 0 End) TodaySum,
Sum(Case When (date = CURDATE()-1)
Then value Else 0 End) PreviousSum
FROM tbl1
group by id, name
Here's a hypothetical query that would do it.
SELECT t1.value AS value_today,(SELECT t2.value FROM table AS t2 WHERE t2.date=2018-01-29 ) AS value_pre
FROM table AS t1 WHERE t1.date=2018-01-28
How to count records base on a specific Year and Month? Eg, that I want to make is as below,
| Category | Total |
|-----------|--------|
| Cat 1 | 15 |
| Cat 2 | 0 |
| Cat 3 | 20 |
| Cat 4 | 18 |
This is the query that I did,
SELECT kc.jenis_katCuti, count(pc.id) AS jum_cuti
FROM permohonan_cuti pc
RIGHT JOIN kat_cuti kc on kc.katCuti_id=pc.katCuti_id
WHERE YEAR(pc.tarikh_mula)=2017 AND MONTH(pc.tarikh_mula)=1
GROUP BY kc.jenis_katCuti
From the query, it will display only for the Year and Month that user choose. I want it to display all the records and return 0 if there is no record for the particular month and year.
I also tried below but still with no success,
SELECT kc.jenis_katCuti, count(YEAR(pc.tarikh_mula)=2017
AND MONTH(pc.tarikh_mula)=1) AS jum_cuti
FROM permohonan_cuti pc
RIGHT JOIN kat_cuti kc on kc.katCuti_id=pc.katCuti_id
GROUP BY kc.jenis_katCuti
Use case when in count like this:
SELECT
kc.jenis_katCuti,
count(CASE WHEN YEAR(pc.tarikh_mula) = 2017 AND MONTH(pc.tarikh_mula) = 1 THEN 1 ELSE NULL END) AS jum_cuti
FROM permohonan_cuti pc
RIGHT JOIN kat_cuti kc on kc.katCuti_id = pc.katCuti_id
GROUP BY kc.jenis_katCuti
cause count only excludes null, the expression YEAR(pc.tarikh_mula) = 2017 AND MONTH(pc.tarikh_mula) = 1 will return 1 or 0, count will include both of them.
If you just use YEAR(pc.tarikh_mula) = 2017 AND MONTH(pc.tarikh_mula) = 1, try sum:
SELECT
kc.jenis_katCuti,
sum(YEAR(pc.tarikh_mula) = 2017 AND MONTH(pc.tarikh_mula) = 1) AS jum_cuti
FROM permohonan_cuti pc
RIGHT JOIN kat_cuti kc on kc.katCuti_id = pc.katCuti_id
GROUP BY kc.jenis_katCuti
I've a table like attached.
I want to find the "number of items in a certain month which has maximum entries in the database".
For instance, Jan has 10 entries, Feb has 13 entries, Mar has 8 entries.
I want to find the the number 13 for Feb from the database as it has the max entries. How do I check the time range in the query?
You can group all of your realeasedates by month and year to get a count like this:
SELECT MONTH(releasedate) AS month, YEAR(releasedate) as year, count(r_id) AS number
FROM my_table
GROUP BY YEAR(releasedate), MONTH(releasedate)
ORDER BY YEAR(releasedate), MONTH(releasedate)
This'll give you something like this:
+--------+--------+--------+
| month | year | number |
+--------+--------+--------+
| 1 | 2013 | 13 |
| 2 | 2013 | 8 |
Then you could select the maximum like this:
SELECT MONTH(releasedate) AS month, YEAR(releasedate) as year, count(r_id) AS number
FROM my_table
GROUP BY YEAR(releasedate), MONTH(releasedate)
ORDER BY count(r_id)
LIMIT 1
Which'll give you:
+--------+--------+--------+
| month | year | number |
+--------+--------+--------+
| 4 | 2013 | 19 |
+--------+--------+--------+
Which'll represent the highest month
SELECT COUNT(*) FROM `mytable` WHERE releasedate >= DATE '2013-02-01' AND releasedate <= DATE '2013-02-28'
That should work
EDIT:
As suggested by lafor...
WHERE YEAR(releasedate)=2013 AND MONTH(releasedate)=2
should also work
I have a database with the following format:
myTable
productgroupID | productID | views | date
1 | 10 | 25 | 2013-05-23
4 | 105 | 15 | 2013-05-23
7 | 60 | 65 | 2013-05-23
7 | 60 | 55 | 2013-05-22
7 | 60 | 45 | 2013-05-21
Now I want to sum all views of a product in the moth May.
Result should be:
productgroupID | productID | viewed | month
7 | 60 | 165 | 2013-05-01
1 | 10 | 25 | 2013-05-01
4 | 105 | 15 | 2013-05-01
I tried the query below, but this gives me all views of a specific productgroupID. But I need the sum of the unique productgroupID & productID.
SELECT COUNT( views ) AS viewed, productgroupID FROM product_stats_daily GROUP BY productgroupID
If you want the views totaled, then you can use the sum() aggregate function and then you can group by the month and year for the date:
select productGroupId,
productId,
sum(views) viewed,
month(date) Month,
year(date) Year
from myTable
group by productGroupId, productId, month(date), year(date);
See SQL Fiddle with Demo
You could also use Date_Format to get the date in the format that you want:
select productGroupId,
productId,
sum(views) viewed,
DATE_FORMAT(date, '%Y-%m-01') date
from myTable
group by productGroupId, productId, DATE_FORMAT(date, '%Y-%m-01')
See SQL Fiddle with Demo
COUNT will count number of rows while SUM will sum up value of retrieved rows.
So your query becomes:
SELECT SUM( views ) AS viewed, productgroupID
FROM product_stats_daily
GROUP BY productgroupID
There's probably a more elegant way to force the date to the beginning of the month, but this should work:
SELECT
ProductGroupID,
ProductID,
SUM(views) AS viewed,
DATE_FORMAT(date, '%Y-%m-01') AS Month
FROM myTable
GROUP BY
ProductGroupID,
ProductID,
DATE_FORMAT(date, '%Y-%m-01')