as described in this question and as its answered with "Not possible" i opened a new question
so my problem goes like this : I have a table (ServiceProvider Table) each service provider have many offers (Offer table) with a OneToMany relation and each Offer have a master service (Service table) with a ManyToOne relation. What i am trying to do is to get all the service providers and their offers in an order related to serviceProvider.points and then serviceProvider.name and each service provider's offers should be ordered by their points. So for more clear view let's say i have the following
ServiceProvider
-------------------------------------------------
id | name | points |offers|
-------------------------------------------------
1 | c | 2 |1,2,3 |
-------------------------------------------------
2 | b | 1 |1,2 |
-------------------------------------------------
3 | a | 0 |1,3 |
-------------------------------------------------
ServiceOffer
-----------------------------------
id | name |service|
-----------------------------------
1 | a | 1 |
-----------------------------------
2 | b | 1 |
-----------------------------------
3 | c | 2 |
-----------------------------------
Service
-----------------------------------
id | name | points |
-----------------------------------
1 | a | 23 |
-----------------------------------
2 | b | 88 |
-----------------------------------
what i exactly need is a result like this
results
service_provider.name| offers.name |
-------------------------------------
c | b , a |
-------------------------------------
b | a , b |
-------------------------------------
a | b , a |
-------------------------------------
this is the query i tried but it's not working
$query->select("sp")
->from("CoreBundle:ServiceProvider","sp")
->andWhere("sp.city = :city_name")->setParameter("city_name",$cityName)
->innerJoin("sp.offers","offer")
->innerJoin("offer.service","service","with","offer.service = service")
->orderBy("sp.points DESC , sp.name ASC , service.points");
needed fields
in serviceProvider
/**
* @var ServiceOffer
*
* @ORM\OneToMany(targetEntity="ServiceOffer", mappedBy="serviceProvider")
*/
private $offers;
in service
/**
* @var integer
*
* @ORM\Column(name="points", type="integer", nullable=true)
*/
private $points;
in service offer
/**
* @ORM\ManyToOne(targetEntity="Service", inversedBy="offer")
* @ORM\JoinColumn(name="service_id", referencedColumnName="id")
*
* @Serializer\Expose
* @Serializer\Groups({"service-offer", "order-entry"})
*
* @Assert\NotBlank(message="constraint.serviceOffer.service.not_blank")
*/
private $service;
You cannot simply enumerate
ORDER BY
directives to Doctrine. You may give a single->orderBy()
method call, giving the field to use and direction (optional,ASC
is default) as arguments, and further order fields must be add using theaddOrderBy
method. Your query should look likeSee the documentation on this topic.
The @SolarBear 's answer is almost correct.
Notice, I remove the unnecessary code in the service Inner Join. And more important, add 'DESC' string in
service.points
order by. It should do the trick.Let's jump to your example :
First of all, I honestly didn't understand you map in column
ServiceProvider.offers
. Second, I change names of these table to be more clear to show the expected result.ServiceProvider
ServiceOffer
Service
results
In this example, SeviceOffer
X
uses ServiceK
(points 88
). While, ServiceOfferY
andZ
use ServiceJ
(points 23
) so there is a draw between the ServiceProviderY
andZ
, so the DB can returns they in any order.Edit
About "offers" column. Notice you mapped as a One to Many relationship. But notice, in the given table example is sound like a Many to Many. Once,
ServiceProvider
has manyServiceOffer
and vice-versa. So for this works properly you should create a join table and removing offers column. And map in ServiceProvider aManyToMany
relationship. Such as:Providers_Offers