Doctrine2 complex ordering - doctrine-orm

I've got a comments table, and each comment has a status like "approved", "awaiting moderation", "hidden". When I show the comments I want them to be sorted according to their statuses - "approved", then "awaiting moderation", then "hidden". I can do that with UNIONs but that's a poor solution performance-wise.
I wonder if there's a Doctrine2 equivalent for "ORDER BY (status <> 'hidden') DESC"? I know about ordering by calculated fields ( Can Doctrine2 #OrderBy a calculated field?) but I don't see how to apply it here.

There is a CASE expression and a HIDDEN keyword if you're using 2.2:
As of Doctrine CaseExpression EBNF, you can use
SELECT
c,
CASE WHEN (c.status = 'hidden') THEN 1 ELSE 0 END AS HIDDEN sortValue
FROM
Comment c
ORDER BY
sortValue DESC

Did you resolve this issue? Another way you can do it, is do an sql query by where you give values to the status, and order by that if you want.
$conn = $entity_manager->getConnection();
$stmt = $conn->query("
select
d.*, case status when 'approved' then 1
when 'awaiting moderation' then 2
when 'hidden' then 3 end sequence
from table order by sequence
");
Just loop threw them.

Related

Optional Column Name for Table.NestedJoin with an Inner JoinKind

In the query below I perform a join on a the Rep table with the Customer to exclude Reps that do not have any customers assigned.
let
...
merge_customer = Table.NestedJoin(
select_columns,{"RepCode"},
Customer,{"CustomerRepCode"},
"Customer",
JoinKind.Inner
),
remove_join_column = Table.RemoveColumns(
merge_customer,
{"Customer"}
)
in
remove_join_column
Because it is an inner join I don't need the resulting Customer column. I then delete that column.
Is there a way to shorten this? I have tried excluding the new column name Customer or passing in null and it only generates an error.
I appreciate this may just not be possible due to the language being quite young but thought I may have missed something in the docs.
Table.Join might do what you want, or after the result of Table.NestedJoin you can add a custom column that calls Table.RemoveColumns on the table column. That would probably look like this (didn't verify the code works):
Table.AddCustomColumn(merge_customer, "InnerColumnRemoved", each Table.RemoveColumns([RepCode], {"Customer"}))
And then you would remove the RepCode column

Django - MyThing.objects.filter(name=None) vs MyThing.objects.filter(name__isnull=True) - which is better?

I have a table and want to find all rows where the name column is None.
Should I do:
MyThing.objects.filter(name=None)
or
MyThing.objects.filter(name__isnull=True)
What difference does it make?
According to the docs for exact and isnull, these produce the same SQL. Which you use is more of a stylistic choice than a performance or correctness one.
A quick check in the console outputted something like the following for me:
str(MyThing.objects.only('name').filter(name=None).query)
# 'SELECT `myapp_mything`.`id`, `myapp_mything`.`name` FROM `myapp_mything` WHERE `myapp_mything`.`name` IS NULL ORDER BY `myapp_mything`.`name` ASC'
str(MyThing.objects.only('name').filter(name__isnull=True).query)
# 'SELECT `myapp_mything`.`id`, `myapp_mything`.`name` FROM `myapp_mything` WHERE `myapp_mything`.`name` IS NULL ORDER BY `myapp_mything`.`name` ASC'
So they appear to be the same.

How to phrase sql query when selecting second table based on information on first table

I have two tables I would like to call, but I am not sure if it is possible to combine them into one query or I have to some how call 2 different queries.
Basically I have 2 tables:
1) item_table: name/id etc. + category ID
2) category_table: categoryID, categoryName, categoryParentID.
The parent categories are also inside the same table with their own name.
I would like to call on my details from item_table, as well as getting the name of the category, as well as the NAME of the parent category.
I know how to get the item_table data, plus the categoryName through an INNER JOIN. But can I use the same query to get the categoryParent's name?
If not, what would be the mist efficient way to do it? The rest of the code is in C++.
SELECT item_table.item_name, c1.name AS CatName, c2.name AS ParentCatName
FROM item_table join category_table c1 on item_table.categoryID=c1.categoryID
LEFT OUTER JOIN category_table c2 ON c2.categoryID = c1.categoryParentID
SQL Fiddle: here

How to order by a computed value in DQL

I'm trying to order the results of my query by whether or not they match my original entity on a property. I could do this easily in mySQL with the following query:
SELECT * FROM table
ORDER BY prop = 'value' DESC;
However, in Doctrine, when I attempt the following:
// $qb is an instance of query builder
$qb->select('e')
->from('Entity', 'e')
->orderBy('e.prop = :value', 'DESC')
->setParameter('value', 'value');
// grab values
I get a Doctrine syntax error, 'end of string'. I looked into creating a custom function, but that seems like overkill. I'm fairly new to Doctrine, is there a better way to do this?
Since Doctrine ORM 2.2, you can use the HIDDEN keyword and select additional fields, in this case with a CASE expression:
SELECT
e,
CASE WHEN e.prop = :value THEN 1 ELSE 0 END AS HIDDEN sortCondition
FROM
Entity e
ORDER BY
sortCondition DESC
As I struggeled a while to figure out how to create that query using php syntax here's what I came up with:
$value = 'my-value';
$qb->select('e')
->from('Entity', 'e')
->addSelect('CASE WHEN e.prop = :value THEN 1 ELSE 0 END AS HIDDEN sortCondition')
->setParameter('value', $value)
->addOrderBy('sortCondition', 'DESC');

query builder select the id from leftJoin

I have a select field that fetch from an entity
and I would like to customize completely my select by choosing the table the id is picked from
(here I would like to select t.id instead of tl.id as the select value)
return $er->createQueryBuilder('tl')
->addSelect('l')
->addSelect('t')
->leftJoin('tl.lang', 'l')
->leftJoin('tl.type', 't')
->where('l.isDefault = 1')
->orderBy('tl.name', 'ASC');
Due to my tables, I can't simply fetch the table t, I have to use tl
Your query is not according to the syntax defined in Doctrine 2 QueryBuilder: http://www.doctrine-project.org/docs/orm/2.0/en/reference/query-builder.html
Your query might work in Doctrine 1.2 but in Doctrine 2 you should build your query according to the syntax defined in the link I posted above.
For example ->addSelect('l') is not being used in Doctrine 2 anymore. It has become ->add('select', 'l').
You don't have to set different alias for your column. It'll be hydrated as column of the related entity.