mysql query get max and distinct value from table - php

this is my original table
+--------+-----------------------+
|cTotal | dateT |
+--------+-----------------------+
| 4 | 2015-07-21 22:41:03 |
| 7 | 2015-08-21 01:21:12 |
| 10 | 2015-08-21 04:35:06 |
| 16 | 2015-09-21 12:20:05 |
| 23 | 2015-09-21 16:51:24 |
| 48 | 2015-10-21 02:11:08 |
+--------+-----------------------+
I use STR_TO_DATE and get
+--------+--------------+
|cTotal | dateT |
+--------+--------------+
| 4 | 2015-07-21 |
| 7 | 2015-08-21 |
| 10 | 2015-08-21 |
| 16 | 2015-09-21 |
| 23 | 2015-09-21 |
| 48 | 2015-10-21 |
+--------+--------------+
But I want the max value of cTotal from each distinct date, something like this:
+--------+--------------+
|cTotal | dateT |
+--------+--------------+
| 4 | 2015-07-21 |
| 10 | 2015-08-21 |
| 23 | 2015-09-21 |
| 48 | 2015-10-21 |
+--------+--------------+
but I don't get the results I want.
SELECT STR_TO_DATE( `dateT` , '%Y-%m-%d' ) AS `dateL`, `cTotal`
FROM `pstable`
INNER JOIN (
SELECT STR_TO_DATE( `dateT , '%Y-%m-%d' ) AS `dateL1` , MAX( `cTotal` ) AS `MaxCDay`
FROM `pstable`
GROUP BY `dateLikes`
) `grouped`
ON `pstable`.`dateL` = `grouped`.`dateL1`
AND `pstable`.`cTotal` = `grouped`.`MaxCDay`

SELECT date(dateT) as theDate, max(cTotal) as cTotal
FROM myTable
GROUP BY date(dateT)
ORDER BY cTotal

You can do this on your original table:
select max(cTotal), dateT from table1
group by str_to_date(dateT,'%Y-%m-%d');
See the SQLFiddle demo here.

select max(cTotal), DATE(dateT) from table_name group by DATE(dateT)

Related

PHP Codeigniter MySQL query - join 4 tables together, with 3 tables using group by one column from each table

Items Table
+----+------+
| id | name |
+----+------+
| 1 | abc |
| 2 | def |
| 3 | ghi |
+----+------+
Buy Table
+------+-------------+-------+---------+
| b_id | b_date | b_qty | b_itmid |
+------+-------------+-------+---------+
| 1 | 2020-05-01 | 10 | 1 |
| 2 | 2020-05-01 | 20 | 1 |
| 3 | 2020-05-02 | 5 | 2 |
| 3 | 2020-05-03 | 10 | 3 |
+------+-------------+-------+---------+
Rent Table
+------+-------------+-------+---------+
| r_id | r_date | r_qty | r_itmid |
+------+-------------+-------+---------+
| 1 | 2020-05-03 | 5 | 2 |
| 2 | 2020-05-03 | 10 | 2 |
| 3 | 2020-05-04 | 15 | 3 |
+------+-----------+---------+---------+
Sell Table
+------+-------------+-------+---------+
| s_id | s_date | s_qty | s_itmid |
+------+-------------+-------+---------+
| 1 | 2020-05-03 | 10 | 1 |
| 2 | 2020-05-05 | 20 | 3 |
| 3 | 2020-05-06 | 5 | 3 |
+------+-----------+---------+---------+
And I'm trying to get outputs with php foreach something like this ...
$trans_date
$buy_qty
$rent_qty
$sell_qty
$item
In case item id 1
+-------------+--------------+---------------+---------------+------+
| trans_date | buy_qty | rent_qty | sell_qty | item |
+-------------+--------------+---------------+---------------+------+
| 2020-05-01 | 30 | 0 | 0 | abc |
| 2020-05-02 | 0 | 0 | 0 | abc |
| 2020-05-03 | 0 | 0 | 10 | abc |
| 2020-05-04 | 0 | 0 | 0 | abc |
| 2020-05-05 | 0 | 0 | 0 | abc |
| 2020-05-06 | 0 | 0 | 0 | abc |
+-------------+--------------+---------------+---------------+------+
This is the query I've come for one table (b_date column has timestamp value)...
$query = $this->db->query("
SELECT FROM_UNIXTIME(b_date,'%d %M') AS date_b
, SUM(b_qty) AS qty_b
FROM buytable
WHERE b_itmid = 1
AND MONTH(FROM_UNIXTIME(b_date)) = MONTH(CURDATE())
GROUP
BY DATE(FROM_UNIXTIME(b_date))
");
if ($query->num_rows() > 0) {
foreach ($query->result() as $data) {
$result[] = $data;
}
return $result;
}
Finally I've found the correct answer https://stackoverflow.com/a/61875506/7554875
select d.date, b.qty_buy, r.qty_rent, s.qty_sell, i.name
from items i
cross join (
select b_date as date from buy
union all select r_date as date from rent
union all select s_date as date from sell
) d
left join (select b_date as date, b_itmid, sum(b_qty) qty_buy
from buy group by date, b_itmid) b
on b.date = d.date and b.b_itmid = i.id
left join (select r_date as date, r_itmid, sum(r_qty) qty_rent
from rent group by date, r_itmid) r
on r.date = d.date and r.r_itmid = i.id
left join (select s_date as date, s_itmid, sum(s_qty) qty_sell
from sell group by date, s_itmid) s
on s.date = d.date and s.b_itmid = i.id
where i.id = 1 and d.date >= date_format(curent_date, '%Y-%m-01')
order by d.date

MySql query in same column for different date

Please consider: I am talking about MySQL Database
I have two tables like this:
tbl_stock_info
+-----+--------+
| sId | sName |
+-----+--------+
| 1 | Apple |
| 2 | Google |
| 3 | Yahoo |
+-----+--------+
tbl_stock_data
+------------+----------+-------------+
| date | stock_id | stock_price |
+------------+----------+-------------+
| 2017-01-25 | 1 | 44.7 |
| 2017-01-25 | 3 | 51 |
| 2017-01-25 | 2 | 71.5 |
| 2017-01-24 | 1 | 44.9 |
| 2017-01-24 | 3 | 51.2 |
| 2017-01-24 | 2 | 71.3 |
+------------+----------+-------------+
The Output I am looking for is like this:
+-----+--------+----------+----------+
| sId | sName | Price_25 | Price_24 |
+-----+--------+----------+----------+
| 1 | Apple | 44.7 | 44.9 |
| 2 | Google | 71.5 | 71.3 |
| 3 | Yahoo | 51 | 51.2 |
+-----+--------+----------+----------+
Any assistance would be greatly appreciated.
You can do it with a query like this. it search the newest 2 dates in the table and generate your query, but the column name are fix. if you want also to change them you must use a prepared statement.
SELECT
si.*
,SUM(if(sd1.`date` = ( SELECT DISTINCT `date` FROM tbl_stock_data ORDER BY `date` DESC LIMIT 0,1), sd1.stock_price ,0) ) as lastday
,SUM(if(sd1.`date` = ( SELECT DISTINCT `date` FROM tbl_stock_data ORDER BY `date` DESC LIMIT 1,1), sd1.stock_price ,0) ) as daybefore
FROM tbl_stock_info si
LEFT JOIN tbl_stock_data sd1 ON sd1.stockid = si.sId
GROUP BY si.sId;
sample
MariaDB [l]> SELECT * FROM tbl_stock_info;
+-----+--------+
| sId | sNAme |
+-----+--------+
| 1 | Apple |
| 2 | Google |
| 3 | Yahoo |
+-----+--------+
3 rows in set (0.00 sec)
MariaDB [l]> SELECT * FROM tbl_stock_data;
+----+------------+---------+-------------+
| id | date | stockid | stock_price |
+----+------------+---------+-------------+
| 1 | 2017-01-25 | 1 | 44.70 |
| 2 | 2017-01-25 | 3 | 51.00 |
| 3 | 2017-01-25 | 2 | 71.50 |
| 4 | 2017-01-24 | 1 | 44.90 |
| 5 | 2017-01-24 | 3 | 51.20 |
| 6 | 2017-01-24 | 2 | 71.30 |
| 7 | 2017-01-23 | 1 | 99.00 |
| 8 | 2017-01-22 | 2 | 22.00 |
| 9 | 2017-01-20 | 3 | 33.13 |
+----+------------+---------+-------------+
9 rows in set (0.01 sec)
test
MariaDB [l]> SELECT
-> si.*
-> ,SUM(if(sd1.`date` = ( SELECT DISTINCT `date` FROM tbl_stock_data ORDER BY `date` DESC LIMIT 0,1), sd1.stock_price ,0) ) as lastday
-> ,SUM(if(sd1.`date` = ( SELECT DISTINCT `date` FROM tbl_stock_data ORDER BY `date` DESC LIMIT 1,1), sd1.stock_price ,0) ) as daybefore
-> FROM tbl_stock_info si
-> LEFT JOIN tbl_stock_data sd1 ON sd1.stockid = si.sId
-> GROUP BY si.sId;
+-----+--------+---------+-----------+
| sId | sNAme | lastday | daybefore |
+-----+--------+---------+-----------+
| 1 | Apple | 44.70 | 44.90 |
| 2 | Google | 71.50 | 71.30 |
| 3 | Yahoo | 51.00 | 51.20 |
+-----+--------+---------+-----------+
3 rows in set (0.00 sec)
MariaDB [l]>

Symfony - Subquery in doctrine2

I have a set of posts on monthly basis. i need an array which contains total records of posts posted in each month (including zeros).
I fail to write it in dql :( Any ideas plz ?
Sample Data:
+----+---------------------+
| id | date |
+----+---------------------+
| 24 | 2012-12-16 16:29:56 |
| 1 | 2013-02-25 14:57:09 |
| 2 | 2013-02-25 14:59:37 |
| 4 | 2013-02-25 15:12:44 |
| 5 | 2013-02-25 15:14:18 |
| 7 | 2013-02-26 11:31:31 |
| 8 | 2013-02-26 11:31:59 |
| 10 | 2013-02-26 11:34:47 |
| 14 | 2013-03-04 04:39:02 |
| 15 | 2013-03-04 05:44:44 |
| 16 | 2013-03-04 05:48:29 |
| 19 | 2013-03-07 15:22:34 |
| 20 | 2013-03-15 12:24:43 |
| 21 | 2013-03-16 16:27:43 |
| 22 | 2013-03-16 16:29:28 |
| 23 | 2013-03-16 16:29:56 |
| 11 | 2013-03-17 11:35:12 |
+----+---------------------+
SQL query:
SELECT count(b.id) as totalRec
FROM (
SELECT 'January' mnth
UNION ALL
SELECT 'February' mnth
UNION ALL
SELECT 'March' mnth
) a
LEFT JOIN post b
ON a.mnth = DATE_FORMAT(b.date, '%M') AND
year(b.date) = '2013' AND
DATE_FORMAT(b.date, '%M') IN ('January', 'February', 'March')
GROUP BY year(b.date)-month(b.date)
ORDER BY b.date ASC
OUTPUT
+----------+
| totalRec |
+----------+
| 0 |
| 7 |
| 9 |
+----------+
Count all posts grouped by month, and filter out the months you want:
SELECT count(*) as totalRec, DATE_FORMAT(b.date, '%m%Y') as month
FROM post b
WHERE month IN('012013', '022013', '032013')
GROUP BY month
ORDER BY b.date ASC
Will result in:
+----------+----------+
| totalRec | month |
+----------+----------+
| 0 | 012013 |
| 7 | 022013 |
| 9 | 032013 |
+----------+----------+

Mysql select distinct id's and select first row only

This is my table. I want to select distinct 'bill_no' with only first related row.
+--------------+--------------+-------+------------+
| id | bill_no | product_name | tax | total |
+--------------+-------+------+-------+------------+
| 1 | 12 | Hairgel | 10 | 241 |
| 2 | 12 | Spiker gel | 10 | 300 |
| 3 | 13 | Wokzem amba | 12 | 450 |
| 4 | 13 | test prod | 1 | 145 |
| 5 | 14 | wokk | 3 | 55 |
| 6 | 14 | Kamer hyp | 11 | 46 |
| 7 | 15 | Xyombokx | 2 | 220 |
+--------------+-------+------+-------+------------+
I want data to be displayed like the below table having only distinct "bill_no" -
Output-
+--------------+--------------+-------+------------+
| id | bill_no | product_name | tax | total |
+--------------+-------+------+-------+------------+
| 1 | 12 | Hairgel | 10 | 241 |
| 3 | 13 | Wokzem amba | 12 | 450 |
| 5 | 14 | wokk | 3 | 55 |
| 7 | 15 | Xyombokx | 2 | 220 |
+--------------+-------+------+-------+------------+
Use group by
select * from youtable group by bill_no
select t1.*
from your_table t1
join
(
select min(id) as id
from your_table
group by bill_no
) t2 on t1.id = t2.id
You can use GROUP BY clause.GROUP BY clause always return first row with related group by cloumn name.
SELECT * FROM `table_1` group by `bill_no`

SQLite foreach type of row

I have got table for example
+------+--------+--------+---------------------+
| Type | Value1 | Value2 | DateAdded |
+------+--------+--------+---------------------+
| 1 | a | a | 2014-03-31 20:00:00 |
| 2 | a | a | 2014-03-31 20:00:10 |
| 3 | a | a | 2014-03-31 20:00:25 |
| 1 | a | a | 2014-03-31 20:00:40 |
| 2 | a | a | 2014-03-31 20:00:50 |
| 3 | a | a | 2014-03-31 20:00:60 |
| 1 | a | a | 2014-03-31 20:01:10 |
| 2 | a | a | 2014-03-31 20:01:25 |
| 3 | a | a | 2014-03-31 20:01:35 |
+------+--------+--------+---------------------+
and many more rows... I want to to recieve in a single query:
20 rows WHERE type = 1 ORDER BY DateAdded DESC
20 rows WHERE type = 2 ORDER BY DateAdded DESC
20 rows WHERE type = 3 ORDER BY DateAdded DESC
and there can be more than three types.
One approach to this type of query is the count(*) in a subquery approach:
select *
from table t
where 20 >= (select count(*)
from table t2
where t2.type = t.type and
t2.DateAdded >= t.DateAdded
);
Count the number of rows with the same time that have a larger DateAdded and choose the ones that have up to 20 of them.

Categories