Symfony - Subquery in doctrine2 - php

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 |
+----------+----------+

Related

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]>

mysql query get max and distinct value from table

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)

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.

SQL request for several tables and operations in MySQL

I have the following 3 tables: unit, stage, stats.
unit stage
+----+--------+ +----+-------+---------------------+
| id | status | | id |unit_id| date |
+----+--------+ +----+-------+---------------------+
| 1 | 2 | | 1 | 2 | 2013-11-22 00:00:00 |
| 2 | 3 | | 2 | 2 | 2013-11-26 12:00:00 |
| 3 | 3 | | 3 | 3 | 2013-10-11 00:00:00 |
| 4 | 0 | | 4 | 1 | 2013-12-29 00:00:00 |
+----+--------+ +----+-------+---------------------+
stats
+----+----------+---------------------+-------+
| id | stage_id | date | clicks|
+----+----------+---------------------+-------+
| 1 | 1 | 2013-11-22 00:00:00 | 10 |
| 2 | 1 | 2013-11-23 00:00:00 | 20 |
| 3 | 1 | 2013-11-24 00:00:00 | 25 |
| 4 | 2 | 2013-11-26 00:00:00 | 15 |
| 5 | 2 | 2013-11-27 12:00:00 | 21 |
| 6 | 3 | 2013-12-29 00:00:00 | 8 |
+----+----------+---------------------+-------+
I need a request, that will produce the following response:
+---------+---------------------+-----------------------+
| unit.id | stage.min.date | sum(stats.max.clicks) |
+---------+---------------------+-----------------------+
| 2 | 2013-11-22 00:00:00 | 46 |
| 3 | 2013-12-29 00:00:00 | 8 |
+---------+---------------------+-----------------------+
by the following rules:
1) unit.id - show only units with unit.status=3
2) stage.min.date - minimal stage.date for corresponding unit_id
3) sum(stats.max.clicks) - sum of stats.clicks with max dvalues for each stage_id associated with corresponding unit_id. In my example 46 = 25(stage_id=1) + 21(stage_id=2)
The problem is in min.date and sum of clicks - I have no idea how to get it in one query. Definitely it`s not a problem to do it using php code and several requests.
Schema in SQL Fiddle
Thanks in advance.
I just ask myself, why I do this? Your example resonse has an error, and does not match your fiddle... but:
SELECT
cc.unit_id, MIN(cc.date) as stage_min_date , SUM(dd.clicks) as stats_max_clicks
FROM
stage cc
LEFT JOIN (
SELECT
bb.stage_id, bb.clicks
FROM
stats bb LEFT JOIN (
SELECT id, stage_id, MAX(date) AS max_date
FROM stats
GROUP BY stage_id
) aa
ON
aa.max_date = bb.date
WHERE
aa.max_date IS NOT NULL
) dd
ON cc.id = dd.stage_id
LEFT JOIN unit ee
ON ee.id = cc.unit_id
WHERE ee.status = 3
GROUP BY cc.unit_id
...

Categories