Doctrine 2 does not recognize SELECT on the FROM clause - mysql

I have a SQL query I would like to use in Doctrine2.
My query, goes to the dabatase, does a GROUP BY user state and COUNT the number of users per state.
Then I'm trying to join a table to COUNT all users and make a percent for every state.
return $this->getEntityManager()
->createQuery("
SELECT COUNT(u.id) as total,
(100*(COUNT( u.id ) / total_users.total)) as percent
FROM UserBundle:User u,
(SELECT COUNT(*) as total
FROM UserBundle:User) as total_users
LEFT JOIN u.idUserEstado ue
GROUP BY u.idUserEstado")
->getResult();
The problem is, when I run the Doctrine2 query I get an exception:
[Semantical Error] line 0, col 397 near
'(SELECT COUNT(': Error: Class '(' is not defined.
Doctrine does not recognize that SELECT on the FROM clause.

Select on the from clause are not handled by doctrine 2
There is a closed (and not accepted) feature request on doctrine's jira : http://www.doctrine-project.org/jira/browse/DDC-2793
DQL is about querying objects. Supporting subselects in the FROM
clause means that the DQL parser is not able to build the result set
mapping anymore (as the fields returned by the subquery may not match
the object anymore). This is why it cannot be supported (supporting it
only for the case you run the query without the hydration is a no-go
IMO as it would mean that the query parsing needs to be dependant of
the execution mode).

(SELECT COUNT( * ) as total FROM UserBundle:User) as total_users
COUNT(*) may not exists in DQL. Try COUNT(u.id), the results will be the same. You also have the possibility to try this in an EntityRepository :
$qb->select(array(
'count(u.id) as total',
'(100*(count(u.id)/total_users.total)) as percent',
'select count(u.id) as total_users) as total_users'))
->from('UserBundle:User')
->leftJoin('u.idUserEstado','ue')
->groupBy('u.idUserEstado');
return $qb->getQuery()->getResult();
Source: Google UserGroup issue

the
... FROM UserBundle:User u, ...
is strange. Maybe it can't find the class User.

Related

View created from valid SQL statement returns error "#1242 - Subquery returns more than 1 row"

When I run the below SQL statement, it correctly shows me what I expect:
SELECT Users.idQuiz as ThisIDQuiz,Rounds.RoundNr as ThisRoundNr, Questions.QuestionNr as ThisQuestionNr, Answer as ThisAnswer, Questions.QuestionScore AS QuestionScoreMax,AnswerCorrect,
(SELECT COUNT(*) as "Aantal Ploegen met dit antwoord"
FROM `Answers`
JOIN Questions on Answers.idQuestion = Questions.idQuestion
JOIN Rounds on Questions.idRound = Rounds.idRound
JOIN Users on Users.idUser = Answers.idUser
where (Users.idQuiz = ThisIDQuiz AND Rounds.RoundNr = ThisRoundNr AND Questions.QuestionNr=ThisQuestionNr AND Answers.Answer = ThisAnswer )
GROUP BY Users.idQuiz,Rounds.RoundNr, Questions.QuestionNr,Answer
) as NrOfTeamsWithThisAnswer,
(SELECT COUNT(*)
FROM Users
WHERE ((Users.idQuiz = ThisIDQuiz) AND (Users.UserType = 0))
) As TotalNrOfTeams,
AnswerCorrect *((Select TotalNrOfTeams)- (SELECT NrOfTeamsWithThisAnswer))as ScoreForThisAnswer
FROM `Answers`
JOIN Questions on Answers.idQuestion = Questions.idQuestion
JOIN Rounds on Questions.idRound = Rounds.idRound
JOIN Users on Users.idUser = Answers.idUser
WHERE Questions.QuestionType = 5
GROUP BY ThisAnswer
ORDER BY ThisIDQuiz, ThisRoundNr, ThisQuestionNr, ThisAnswer;
See Results of the query for what the result looks like.
I then create a VIEW from this statement. The view is created fine, but when I open it, I get the error "#1242 - Subquery returns more than 1 row".
I tried dropping and recreating the view, same result.
When I use the exact same SQL statement but without the penultimate line (GROUP BY ThisAnswer), it works fine (i.e. I can create the view and it opens without an error). This second view suits my purposes fine, so I can continue, but just out of curiosity: can someone explain this behaviour?
I use phpMyAdmin version 5.1.3 to do my SQL manipulations.
As #NickW asks, the statement GROUP BY ThisAnswer expects you to have an aggregate function (i.e. count, avg, max, min, etc.) somewhere in that main SELECT. Having a GROUP BY without an aggregate function will create errors. Either add the aggregate function, or remove the GROUP BY statement in the main (outermost) SELECT.

How can I replace WHERE IN choices in WHERE clause to reduce execution time of the request?

I am using DBF database in a C++ project written on RAD Studio 10.2 Tokyo. To make request on this database, I am using UniDac Devart component (that is a little bit limited compared to MySQL itself). The problem I have is when using WHERE IN condition in the request, the request makes too much time to be execute (more than one hour sometimes).
This is the request I have :
SELECT accountrp, SUM(amounteur) AS montant FROM %s
WHERE doctype='1' AND period<>'00' AND
matchno IN(SELECT matchno FROM %s GROUP BY matchno HAVING SUM(amounteur)<>0)
GROUP BY accountrp
accountrp, doctype, period are character and amounteur is numeric.
The problem is around the line matchno IN. I would like to optimize the request without using IN. I saw on Internet that WHERE IN condition can be replaced by INNER JOIN junctions but I Don't know if it is the solution and how to do this.
Can you help me, please ?
A first suggestion
you could change the IN clause in a INNER JOIN
this should be more efficent for performance
SELECT accountrp,
SUM(amounteur) AS montant
FROM %s as s
INNER JOIN (
SELECT matchno
FROM %s
GROUP BY matchno
HAVING SUM(amounteur)<>0
) t on t.matchno = s.matchno
WHERE doctype='1' AND period<>'00' AND
GROUP BY accountrp
this because a In clause is equivalent to a set of OR condition and the query is performed each time for each OR .. a inner join instead is just a join between tow table and is performed just one time
You can try with below
SELECT s.accountrp, SUM(s.amounteur) AS montant FROM %s s
join
(SELECT matchno FROM %s GROUP BY matchno HAVING SUM(amounteur)<>0) t
on s.matchno =t.matchno
WHERE s.doctype='1' AND s.period<>'00'
GROUP BY s.accountrp

Using a COUNT value in an expression getting..does not include specified expression as part of an aggregate function

I am trying to display a warning if a bike station gets to over 90% full or less than 10% full. When i run this query I get "you are trying to execute query that does not include the iif statment... as part of an aggregate function.
Bike_locations table - Bicycle_id and Locations_ID
Locations table - Locations_ID, No_of_Spaces, Location_Address
SELECT Locations.Location_Address, Count(Bike_Locations.Bicycle_ID) AS CountOfBicycle_ID,
IIf(((([CountOfBicycle_ID]/[LOCATIONS]![No_Of_Spaces])*100)>90),"This Station is nearly full.
Need to move some bicycles out of here",IIf(((([CountOfBicycle_ID]/[LOCATIONS]![No_Of_Spaces])*100)
<10),"This station is nearly empty. Need to move some bicycles here","")) AS Warnings
FROM Locations INNER JOIN Bike_Locations ON Locations.[LOCATIONS_ID] = Bike_Locations.[LOCATIONS_ID]
GROUP BY Locations.Location_Address;
Anyone got a scooby
When you use a GROUP BY, you should have the exact same fields in both your SELECT and GROUP BY statements, except for the aggregate function that should only be specified in the SELECT
The aggregate function in your case is the COUNT(*)
The fields you aggregate on are:
in the SELECT : Location_Address and Warnings
in the GROUP BY : Location_Address only
The error message is telling you that you don't have the same in both statements.
2 solutions:
Remove the Warnings from the SELECT statement
Add the Warnings to the GROUP BY statement
Note that in MS Access SQL, you can't (unfortunately) use in the GROUP BY, the Aliases specified in the SELECT. So you have to copy over the whole field, which would be the long iif in your case
Edit: better solution proposal:
I would radically change your approach as you'll go no where with all those nested iff
Create the following Query and Name it (for instance) Stations_Occupation
SELECT L.Locations_ID AS ID,
L.Location_Address AS Addr,
L.No_of_Spaces AS TotSpace,
BL.cnt AS OccSpace,
ROUND((BL.cnt/L.No_of_Spaces*100),0) AS OccPourc
FROM Locations L
LEFT JOIN
(
SELECT Locations_ID, COUNT(*) AS cnt
FROM Bike_Locations
GROUP BY LOCATIONS_ID
) AS BL ON L.Locations_ID = BL.Locations_ID
This query will probably be a lot helpfull in many parts of your application, and not only here, as it calculates the occupation % of each station
Some examples:
Get all stations with >90% occupation:
SELECT Addr
FROM Stations_Occupation
WHERE OccPourc > 90
Get all stations with <10% occupation:
SELECT Addr
FROM Stations_Occupation
WHERE OccPourc < 10
Get Occupation level of a specific station:
SELECT OccPourc
FROM Stations_Occupation
WHERE ID=specific_station_ID
Get number of bikes and max on a specific station:
SELECT OccSpace & "/" & TotSpace
FROM Stations_Occupation
WHERE ID=specific_station_ID

Error Converting MySQL Query to SQL Server

Trying to convert below query into SQL, query works fine on MySQL. Problem seems to be the GROUP BY area. Even when I use just 1 GROUP BY field I get same error. Using query in InformaticaCloud.
ERROR
"the FROM Config_21Cent WHERE resp_ind = 'Insurance' GROUP BY
resp_Ind;;] is empty in JDBC connection:
[jdbc:informatica:sqlserver://cbo-aps-inrpt03:1433;DatabaseName=SalesForce]."
SELECT sum(Cast(Resp_Ins_Open_dol AS decimal(10,2))) as baltotal,
carrier_code,
carrier_name,
carrier_grouping,
collector_name,
dataset_loaded,
docnum,
envoy_payer_id,
loc,
market,
master_payor_grouping,
plan_class,
plan_name,
resp_ins,
resp_ind,
resp_payor_grouping,
Resp_Plan_Type,
rspphone,
state
FROM Config_21Cent
WHERE resp_ind = 'Insurance'
GROUP BY
(resp_ins + resp_payor_grouping +
carrier_code + state + Collector_Name);
Your entire query isn't going to work. The group by statement contains a single expression, the summation of a bunch of fields. The select statement contains zillions of columns without aggregates. Perhaps you intend for something like this:
select resp_ins, resp_payor_grouping, carrier_code, state, Collector_Name,
sum(Cast(Resp_Ins_Open_dol AS decimal(10,2))) as baltotal
from Config_21Cent
WHERE resp_ind = 'Insurance'
GROUP BY resp_ins, resp_payor_grouping, carrier_code, state, Collector_Name;
THis will work in both databases.
The columns in SELECT statement must be a subset (not proper subset but subset) of columns in 'GROUP BY' statement. There is no such restriction on aggregates in SELECT statement though. There could be any number of aggregates; aggregates even on columns not in GROUP BY statement can be included.

MySQL COUNT() causing empty array() return

MySQL Server Version: Server version: 4.1.14
MySQL client version: 3.23.49
Tables under discussion: ads_list and ads_cate.
Table Relationship: ads_cate has many ads_list.
Keyed by: ads_cate.id = ads_list.Category.
I am not sure what is going on here, but I am trying to use COUNT() in a simple agreggate query, and I get blank output.
Here is a simple example, this returns expected results:
$queryCats = "SELECT id, cateName FROM ads_cate ORDER BY cateName";
But if I modify it to add the COUNT() and the other query data I get no array return w/ print_r() (no results)?
$queryCats = "SELECT ads_cate.cateName, ads_list.COUNT(ads_cate.id),
FROM ads_cate INNER JOIN ads_list
ON ads_cate.id = ads_list.category
GROUP BY cateName ORDER BY cateName";
Ultimately, I am trying to get a count of ad_list items in each category.
Is there a MySQL version conflict on what I am trying to do here?
NOTE: I spent some time breaking this down, item by item and the COUNT() seems to cause the array() to disappear. And the the JOIN seemed to do the same thing... It does not help I am developing this on a Yahoo server with no access to the php or mysql error settings.
I think your COUNT syntax is wrong. It should be:
COUNT(ads_cate.id)
or
COUNT(ads_list.id)
depending on what you are counting.
Count is an aggregate. means ever return result set at least one
here you be try count ads_list.id not null but that wrong. how say Myke Count(ads_cate.id) or Count(ads_list.id) is better approach
you have inner join ads_cate.id = ads_list.category so Count(ads_cate.id) or COUNT(ads_list.id) is not necessary just count(*)
now if you dont want null add having
only match
SELECT ads_cate.cateName, COUNT(*),
FROM ads_cate INNER JOIN ads_list
ON ads_cate.id = ads_list.category
GROUP BY cateName
having not count(*) is null
ORDER BY cateName
all
SELECT ads_cate.cateName, IFNULL(COUNT(*),0),
FROM ads_cate LEFT JOIN ads_list
ON ads_cate.id = ads_list.category
GROUP BY cateName
ORDER BY cateName
Did you try:
$queryCats = "SELECT ads_cate.cateName, COUNT(ads_cate.id)
FROM ads_cate
JOIN ads_list ON ads_cate.id = ads_list.category
GROUP BY ads_cate.cateName";
I am guessing that you need the category to be in the list, in that case the query here should work. Try it without the ORDER BY first.
You were probably getting errors. Check your server logs.
Also, see what happens when you try this:
SELECT COUNT(*), category
FROM ads_list
GROUP BY category
Your array is empty or disappear because your query has errors:
there should be no comma before the FROM
the "ads_list." prefix before COUNT is incorrect
Please try running that query directly in MySQL and you'll see the errors. Or try echoing the output using mysql_error().
Now, some other points related to your query:
there is no need to do ORDER BY because GROUP BY by default sorts on the grouped column
you are doing a count on the wrong column that will always give you 1
Perhaps you are trying to retrieve the count of ads_list per ads_cate? This might be your query then:
SELECT `ads_cate`.`cateName`, COUNT(`ads_list`.`category`) `cnt_ads_list`
FROM `ads_cate`
INNER JOIN `ads_list` ON `ads_cate`.`id` = `ads_list`.`category`
GROUP BY `cateName`;
Hope it helps?