Doctrine distinct createQueryBuilder - doctrine-orm

I am trying to select MAX scores objects for unique user(s).
So user should be distinct and i should receive max score for a user (order), and I need to get other object values like dataAdded for this max score.
$query = $this->createQueryBuilder('s');
$query->select('DISTINCT s.user, s');
$query->where('s.challenge = :challenge')->setParameter('challenge', $challenge);
$query->andWhere('s.date_added BETWEEN :monday AND :sunday')
->setParameter('monday', $startDate->format('Y-m-d'))
->setParameter('sunday', $endDate->format('Y-m-d'));
$query->orderBy('s.score', 'DESC');
//$query->groupBy('s.user');
$query->setMaxResults($limit);
$results = $query->getQuery();
Does not matter how I try i can't make distinct to work. I have tried group by MAX(s.score) but this will associate random object with max score rather then the same object..
Does anyone have a solution to this? Distinct simply don't seem to work...
Generated query:
SELECT DISTINCT s.user, s FROM Digital\ApplicationBundle\Entity\ChallengeScore s WHERE s.challenge = :challenge AND (s.date_added BETWEEN :monday AND :sunday) ORDER BY s.score DESC
But an error ;(
[Semantical Error] line 0, col 18 near 'user, s FROM': Error: Invalid PathExpression. Must be a StateFieldPathExpression
Its worth to mention that user is a relation. When i try this on other files this works fine...

If you need get count distinct values, you can use countDistinct. But if you must get all distinct values, use groupBy

Related

Column does not exist AWS Timestream Query error

I am trying to apply WHERE clause on DIMENSION of the AWS Timestream records. However, I got the error: Column does not exist
Here is my table schema:
The table schema
The table measure
First, I will show all the sample data I put in the table
SELECT username, time, manual_usage
FROM "meter-reading"."meter-metrics"
ORDER BY time DESC
LIMIT 4
The result:
Result
What I wanted to do is to query and filter the records by the Dimension ("username" specifically).
SELECT *
FROM "meter-reading"."meter-metrics"
WHERE measure_name = "OnceADay"
ORDER BY time DESC LIMIT 10
Then I got the Error: Column 'OnceADay' does not exist
I tried to search for any quotas for Dimensions name and check for error in my schema:
https://docs.aws.amazon.com/timestream/latest/developerguide/ts-limits.html#limits.naming
https://docs.aws.amazon.com/timestream/latest/developerguide/ts-limits.html#limits.system_identifier
But I didn't find that my "username" for the dimension violate any of the above rules.
I checked for some other queries by AWS Blog, the author used the WHERE clause for the Dimension filter normally:
https://aws.amazon.com/blogs/database/effective-queries-for-common-query-patterns-in-amazon-timestream/
I figured it out after I tried with the sample code. Turn out it was a silly mistake I believe.
Using apostrophe (') instead of single quotation marks ("") solved my problem.
SELECT *
FROM "meter-reading"."meter-metrics"
WHERE username = 'OnceADay'
ORDER BY time DESC LIMIT 10

Changing measures with a slicer: "a table of multiple values was supplied where a single value was expected" error message

I followed this blog's instructions to create a slicer that would let me swap between measures in a text table: https://community.powerbi.com/t5/Community-Blog/Dynamically-change-the-information-within-a-visual-via-a-slicer/ba-p/87027
I am getting this error message for the column I am creating in the last step: "a table of multiple values was supplied where a single value was expected":
Select level (% favorable) =
SWITCH( TRUE(),
VALUES ('Measure Dimensions'[Measure]) = "Country", ROUND([c_pct_favorable],1),
VALUES ('Measure Dimensions'[Measure]) = "State", ROUND([s_pct_favorable],1),
VALUES ('Measure Dimensions'[Measure]) = "Zip", ROUND([z_pct_favorable],1),
BLANK())
I am basically trying to swap between country, state, and zip code level % favorable survey data.
Note: I had to add the ROUND calculation because I was getting a 'you can't combine fields with different data types' error message.
I tried Googling this error message but didn't find a use case exactly like mine and couldn't figure out the other article's logic and how it applied to my problem.
Thank you very much for your help!

Is it possible to update a piece of data in a pre-existing table using the output of data from a CTE?

I need to correct a datapoint in a pre-existing table. I am using multiple CTEs to find the bad value and the corresponding good value. I am having trouble working out how to overwrite the value in the table using the output of the CTE. Here is what I am trying:
with [extra CTEs here]....
,CTE3 AS (
SELECT c1.FIELD_1, c1.FIELD_2 AS GOOD, c2.FIELD_3 AS BAD
FROM CTE1 c1
JOIN CTE2 c2 ON c1.FIELD_1 = c2.FIELD_1
)
update TABLE1
set TABLE1.FIELD_3 = CTE3.GOOD
from CTE3
INNER JOIN TABLE1 ON CTE3.BAD = TABLE1.FIELD_3
Is it even possible to achieve this?
If so, how should I change my logic to get it to work?
Trying the above logic is throwing the following error:
SQL Error [42601]: An unexpected token "WITH CTE1 AS ( SELECT
FIELD_1" was found following "BEGIN-OF-STATEMENT". Expected tokens
may include: "<update>".. SQLCODE=-104, SQLSTATE=42601,
DRIVER=4.27.25
Table designs and expected output:

How to count distinct query in Rails 4 with Postgresql?

I have this ActiveRecord query:
Stock.select('DISTINCT ON (stocks.part_number)*').joins(:part, :manufacturer)
.includes(:manufacturer, :part).order(:part_number).with_cat(category).
where(manufacturers: {abbr: ['manufacturer1', 'manufacturer2']})
with_cat is a scope:
scope :with_cat, -> (category) { where(parts: {category_id: category}) }
Now the reason I am using Distinct on is because every manufacturer can have the same part as another, hence duplicates. I do not want duplicates. The above gets the job done. Except when I add count to it I get an error.
PG::SyntaxError: ERROR: syntax error at or near "ON"
LINE 1: SELECT COUNT(DISTINCT ON (stocks.part_number)*) FROM "stocks...
^
: SELECT COUNT(DISTINCT ON (stocks.part_number)*) FROM "stocks"
INNER JOIN "parts" ON "parts"."id" = "stocks"."part_id"
INNER JOIN "manufacturers" ON "manufacturers"."id" = "stocks"."manufacturer_id"
WHERE "parts"."category_id" = 17 AND "manufacturers"."abbr" IN ('manufacturer1', 'manufacturer2')
Not really sure how to add a count to the query without causing that error. I'm not familiar with Distinct on either. Any explanation as to why this is happening would be great!
Does it fix the query if you use the count ahead of distinct? Got the idea per this postgres documentation.
Stock.select('count(distinct part_number)')...

Auto incrementing a virtual column after a GROUP BY, ORDER BY query

I've made extensive research about auto-increment before posting this but couldn't find similar case:
I have a query pulling data from a main table, grouping by player_id and ordering by points desc, therefore creating a ranking output. My aim is to make the same query, once it finishes aggregating and sorting data, create a new column 'Rank' and auto increment it so it shows 1,2,3 etc since everything is already grouped by player and ordered by points DESC.
Thanks guys.
Example of the source table :
player_id-----------points-----
---1-------------------5----------
---1-------------------10---------
---1-------------------5---------
---2-------------------20---------
---2-------------------5---------
Desired output according to this example:
Rank------player_id-------score-----
----1----------2-----------25 POINTS ---------
----2----------1-----------20 POINTS ---------
EDIT
Rownum does the job well, no need for an auto increment virtual column! see Mutnowski's accepted answer below please.
Try this
SELECT #rownum:=#rownum+1 AS ‘rank’, Player_ID, Points FROM (SELECT Player_ID, SUM(Points) AS 'Points' FROM tblScores GROUP BY Player_ID ORDER BY Points DESC) AS foo, (SELECT #rownum:=0) AS foo2
I think you need to run a query to get your results without the rank, then run another query on first that selects all and adds the rank
Applying SUM to the Points column should produce the results you want.
SELECT #rownum:=#rownum+1 AS ‘rank‘,player_id, SUM(points)
FROM scores
GROUP BY player_id
ORDER BY SUM(points) DESC;