how to group by minute with doctrine query builder - doctrine-orm

i want to do run that query with doctrine query builder
select * from stats group by MINUTE(date_time)
i have tried this query builder but thrown exception
[Semantical Error] line 0, col 50 near 'MINUTE(s.dateT': Error: Cannot group by undefined identification or result variable.
$queryBuilder =
$entityManager->createQueryBuilder('Application\Entity\Stats');
$queryBuilder->select('s')
->from('Application\Entity\Stats', 's');
$queryBuilder->groupBy('MINUTE(dateTime)');
how do i group by with minute

The error shows you that you cannot group by result. If you can do it with row SQL just try this
$conn = $entityManager->getConnection();
$sql = "SELECT *, MINUTE(row.date) as m FROM `table` AS row GROUB BY m"
$query = $conn->prepare($sql);
$query->execute;
$query->fetchAll();

Related

how do i loop through tables to get counts

I have tried to use the following, but it seems that different nodes cannot be mixed:
WITH tables_i_want AS (
SELECT *, table_schema||'.'||table_name as tbl FROM temp.redshift_mod_dates WHERE table_schema = 'whatever'
)
SELECT nspname
FROM pg_catalog.pg_class AS c
JOIN pg_catalog.pg_namespace AS ns
ON c.relnamespace = ns.oid
INNER JOIN tables_i_want as tiw
ON tiw.tbl = c.oid
AND relname not like 'pg_%'
so, then I tried a procedure:
CREATE OR REPLACE PROCEDURE f_test()
LANGUAGE plpgsql
AS $$
DECLARE
full_table_name1 VARCHAR;
full_table_name VARCHAR;
BEGIN
FOR full_table_name IN (SELECT table_schema||'.'||table_name as full_table_name FROM temp.redshift_mod_dates WHERE table_schema = 'whatever')
LOOP
EXECUTE 'SELECT INTO temp.redshift_tables_with_cnt %, COUNT(*) FROM %', full_table_name;
RAISE INFO '%', full_table_name;
END LOOP;
END;
$$;
seems there's an issue with the variable:
[42601] ERROR: syntax error at or near "$1" Where: SQL statement in PL/PgSQL function "f_test" near line 5
If you want to receive the row-count for all the tables you could achieve it using the following query
select tab.table_schema,
tab.table_name,
tinf.tbl_rows as rows
from svv_tables tab
join svv_table_info tinf
on tab.table_schema = tinf.schema
and tab.table_name = tinf.table
where tab.table_type = 'BASE TABLE'
and tab.table_schema not in('pg_catalog','information_schema')
and tinf.tbl_rows > 1
order by tinf.tbl_rows desc;
You can have the data stored into a temporary table and then move them to a persistant table or do further processing as required.

Joining 2 results in Doctrine throws error

I am trying to JOIN 2 queries in DQL but I am getting an error which says,
[Semantical Error] line 0, col 114 near '(select u.email': Error: Class '(' is not defined.
I have gone through https://stackoverflow.com/questions/24600439/error-in-nested-subquery-in-dql-class-is-not-defined. But I could not figure out. Please help.
My Query is as follows:
$filterQuery = "SELECT tempResult1.email as email,tempResult1.name as name , tempResult1.id as user
FROM (select u.email as email,a.name as name , u.id as user
FROM
Application\Entity\Userhasrole uhr
INNER JOIN
Application\Entity\Oauthrole r with uhr.applicationrole = r.id
INNER JOIN
Application\Entity\Application a with r.application = a.id
INNER JOIN
Application\Entity\Oauthusers u
) tempResult1
LEFT JOIN
(SELECT uhr1.user as user FROM Application\Entity\Userhasrole uhr1 where
a.id = :applicationId
) tempResult2
with tempResult1.user = tempResult2.user";
$queryObject = $this->getEntityManager()
->createQuery($filterQuery);
$queryObject->setParameter('applicationId', $applicationId);
$result = $queryObject->getResult();
You mix 2 concepts of Doctrine2 :
using SQL
using DQL
If you want to achieve that you want, build tables selections, and not entities selections, you should use EntityManager::createNativeQuery() method and set an SQL query as parameter.
EntityManager::createQuery() is used only for DQL queries

some order by in doctrine query language

I have a query as below :
SELECT t.id, t.name, count(i.id) FROM Acme\TestBundle\Entity\Tags t
LEFT JOIN t.items i WITH i.status=1 AND (SELECT count(img.id) FROM Acme\TestBundle\Entity\ItemsImages img WHERE img.item=i.id) > 0
GROUP BY t.id
ORDER BY COUNT (i.id) DESC
This query works fine without ORDER BY clause. Whenever I add this clause it gives me error :
[Syntax Error] line 0, col 297: Error: Expected end of string, got '('
ORDER BY works with column names but with columns like count(i.id) is not working
To order by an aggregated value, you need to SELECT it first and then use it to ORDER BY:
SELECT
t.id,
t.name,
count(i.id) AS tags_count
FROM
Acme\TestBundle\Entity\Tags t
...
ORDER BY
tags_count DESC

Doctrine join query to get all record satisfies count greater than 1

I tried with normal sql query
SELECT activity_shares.id FROM `activity_shares`
INNER JOIN (SELECT `activity_id` FROM `activity_shares`
GROUP BY `activity_id`
HAVING COUNT(`activity_id`) > 1 ) dup ON activity_shares.activity_id = dup.activity_id
Which gives me record id say 10 and 11
But same query I tried to do in Doctrine query builder,
$qb3=$this->getEntityManager()->createQueryBuilder('c')
->add('select','c.id')
->add('from','MyBundleDataBundle:ActivityShare c')
->innerJoin('c.activity', 'ca')
// ->andWhere('ca.id = c.activity')
->groupBy('ca.id')
->having('count(ca.id)>1');
Edited:
$query3=$qb3->getQuery();
$query3->getResult();
Generated SQL is:
SELECT a0_.id AS id0 FROM activity_shares a0_
INNER JOIN activities a1_ ON a0_.activity_id = a1_.id
GROUP BY a1_.id HAVING count(a1_.id) > 1
Gives only 1 record that is 10.I want to get both.I'm not getting idea where I went wrong.Any idea?
My tables structure is:
ActivityShare
+-----+---------+-----+---
| Id |activity |Share| etc...
+-----+---------+-----+----
| 1 | 1 |1 |
+-----+---------+-----+---
| 2 | 1 | 2 |
+-----+---------+-----+---
Activity is foreign key to Activity table.
I want to get Id's 1 and 2
Simplified SQL
first of all let me simplify that query so it gives the same result :
SELECT id FROM `activity_shares`
GROUP BY `id`
HAVING COUNT(`activity_id`) > 1
Docrtrine QueryBuilder
If you store the id of the activty in the table like you sql suggests:
You can use the simplified SQL to build a query:
$results =$this->getEntityManager()->createQueryBuilder('c')
->add('select','c.id')
->add('from','MyBundleDataBundle:ActivityShare c')
->groupBy('c.id')
->having('count(c.activity)>1');
->getResult();
If you are using association tables ( Doctrine logic)
here you will have to use join but the count may be tricky
Solution 1
use the associative table like an entitiy ( as i see it you only need the id)
Let's say the table name is activityshare_activity
it will have two fields activity_id and activityshare_id, if you find a way to add a new column id to that table and make it Autoincrement + Primary the rest is easy :
the new entity being called ActivityShareActivity
$results =$this->getEntityManager()->createQueryBuilder('c')
->add('select','c.activityshare_id')
->add('from','MyBundleDataBundle:ActivityShareActivity c')
->groupBy('c.activityshare_id')
->having('count(c.activity_id)>1');
->getResult();
the steps to add the new identification column to make it compatible with doctrine (you need to do this once):
add the column (INT , NOT NULL) don' t put the autoincrement yet
ALTER TABLE tableName ADD id INT NOT NULL
Populate the column using a php loop like for
Modify the column to be autoincrement
ALTER TABLE tableName MODIFY id INT NOT NULL AUTO_INCREMENT
Solution2
The correction to your query
$result=$this->getEntityManager()->createQueryBuilder()
->select('c.id')
->from('MyBundleDataBundle:ActivityShare', 'c')
->innerJoin('c.activity', 'ca')
->groupBy('c.id') //note: it's c.id not ca.id
->having('count(ca.id)>1')
->getResult();
I posted this one last because i am not 100% sure of the output of having+ count but it should word just fine :)
Thanks for your answers.I finally managed to get answer
My Doctrine query is:
$subquery=$this->getEntityManager()->createQueryBuilder('as')
->add('select','a.id')
->add('from','MyBundleDataBundle:ActivityShare as')
->innerJoin('as.activity', 'a')
->groupBy('a.id')
->having('count(a.id)>1');
$query=$this->getEntityManager()->createQueryBuilder('c')
->add('select','c.id')
->add('from','ChowzterDataBundle:ActivityShare c')
->innerJoin('c.activity', 'ca');
$query->andWhere($query->expr()->in('ca.id', $subquery->getDql()))
;
$result = $query->getQuery();
print_r($result->getResult());
And SQL looks like:
SELECT a0_.id AS id0 FROM activity_shares a0_ INNER JOIN activities a1_ ON a0_.activity_id = a1_.id WHERE a1_.id IN (SELECT a2_.id FROM activity_shares a3_ INNER JOIN activities a2_ ON a3_.activity_id = a2_.id GROUP BY a2_.id HAVING count(a2_.id) > 1

Doctrine2 DQL select on a resultset (double group by)

I have a complex query that need to be written in DQL / Doctrine2.
The pseudo query (I left out all the extra joins / calculations) is:
SELECT
a, SUM(b)
FROM (
SELECT
a, SUM(b)
FROM tbl
GROUP BY a,c
) calc
GROUP BY a
First a group by on column a and c, and a select with again a group by on a afterwards.
The (pseudo) code on the select part is easy in querybuilder:
$queryBuilder = $this->entityManager->createQueryBuilder();
$queryBuilder
->select(array('tbl'))
->addSelect('SUM(tbl.b)')
->from('\Model\MyModel', 'tbl')
->groupBy('a')
->addGroupBy('c');
$query = $queryBuilder->getQuery();
$results = $query->getResult();
However, how do I query this result again?
Is this possible?
Or can I somehow put them togheter in 1 queryBuilder object?