My scripts stop working after I've upgraded from Doctrine 2.3.6 up to Doctrine 2.5.0 .
I want to perform query with pagination on joined tables. I have two entities: Program and ProgramVersion joined by Program::versions field.
Here is the query:
$query = $em->createQuery('
SELECT m, v
FROM Entity\Program m
LEFT JOIN m.versions v
WITH m.version = v.version
WHERE m.deletedDate IS NULL
ORDER BY m.type asc');
Then I pass the query to Paginator
$pResult = new \Doctrine\ORM\Tools\Pagination\Paginator($query, true);
At the stage when I do $pResult->getIterator() I get the following error message:
An exception occurred while executing '
SELECT DISTINCT id_0
FROM (
SELECT e0_.id AS id_0, e1_.id AS id_27 /* removed a lot of fields here */ FROM entity_program e0_
LEFT JOIN entity_program_version e1_ ON e0_.id = e1_.master_id AND (e0_.version = e1_.version)
WHERE e0_.deleted_date IS NULL
) dctrn_result ORDER BY e0_.type_id ASC':
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'e0_.type_id' in 'order clause'
Obviously the SQL is wrong. The ORDER BY clause is outside of the main SELECT and it contains the field which doesn't exist.
Can anybody help me to solve the issue?
Related
I'm trying to update rows in MySQL from SQL view created with aliases. I do not know if this even is possible.
The original SQL looks like below. This I have saved as a view "ProductVersion".
SELECT e.entity_id AS id,
v1.value AS name,
e.sku,
d1.value AS version
FROM mguu_catalog_product_entity e
LEFT JOIN mguu_catalog_product_entity_varchar v1 ON e.entity_id = v1.entity_id
AND v1.store_id = 0
AND v1.attribute_id =
(SELECT attribute_id
FROM mguu_eav_attribute
WHERE attribute_code = 'name'
AND entity_type_id =
(SELECT entity_type_id
FROM mguu_eav_entity_type
WHERE entity_type_code = 'catalog_product'))
LEFT JOIN mguu_catalog_product_entity_varchar d1 ON e.entity_id = d1.entity_id
AND d1.attribute_id = 171;
Now I would like to perform a MySQL UPDATE from that view, so I tried:
mysqli_query($db, "UPDATE ProductVersion SET version = '123123123' WHERE sku = '1003'");
This does not return any error - however it does not update though. I have also tried like this, but this creates an error:
mysqli_query($db, "UPDATE ProductVersion SET d1.value = '123123123' WHERE e.sku = '1003'");
Is it possible to do an MySQL UPDATE from a view and if not, how would it be done the easiest from the original SQL?
Thanks in advance.
I don't know if that solve the problem but I think you can simplify your View something like this (less useless select statement) :
SELECT e.entity_id AS id,
v1.value AS name,
e.sku as sku,
d1.value AS version
FROM mguu_catalog_product_entity e
LEFT JOIN mguu_catalog_product_entity_varchar v1 ON (e.entity_id = v1.entity_id)
LEFT JOIN mguu_catalog_product_entity_varchar d1 ON (e.entity_id = d1.entity_id)
LEFT JOIN mguu_eav_attribute AS mea ON (v1.attribute_id = mea.attribute_id)
LEFT JOIN mguu_eav_entity_type AS meet ON (meet.entity_type_code = 'catalog_product')
WHERE v1.store_id = 0
AND mea.attribute_code = 'name'
AND mea.entity_type_id = meet.entity_type_id
AND d1.attribute_id = 171;
In MySql documentation :
UPDATE: The table or tables to be updated in an UPDATE statement may be view references that are merged. If a view is a join view, at least one component of the view must be updatable (this differs from INSERT).
In a multiple-table UPDATE statement, the updated table references of the statement must be base tables or updatable view references. Nonupdated table references may be materialized views or derived tables.
https://dev.mysql.com/doc/refman/8.0/en/view-updatability.html
I am creating a message service with Laravel.
I want to display recent messages from all based on time. This is what I am trying to implement
The following are my tables
message table
message_user table
I tried the following code
SELECT DISTINCT user_id,sender
FROM (
SELECT DISTINCT message_user.user_id, messages.sender, messages.created_at
FROM messages
JOIN message_user ON message_user.message_id=messages.id AND message_user.user_id=225
UNION
SELECT DISTINCT message_user.user_id, messages.sender, messages.created_at FROM messages
JOIN message_user ON message_user.message_id=messages.id AND messages.sender=225 AND message_user.user_id NOT IN (
SELECT DISTINCT messages.sender
FROM messages
JOIN message_user ON message_user.message_id=messages.id AND message_user.user_id=225
)
) mytable
ORDER BY created_at
The problem is that the output is not in the expected format (that is not sorted based on created_at)
Following is the corresponding Laravel code I have tried
$id = $request->user()->id;
$user = User::find($id);
$buddylist = $user->messages()->select(DB::raw('message_user.user_id,messages.sender,messages.created_at'));
$subquery = Message::select(DB::raw(' messages.sender'))->join('message_user','messages.id','=','message_user.message_id') ->where("message_user.user_id",'=',$request->user()->id);
$mybuddy = Message::selectRaw('message_user.user_id,messages.sender,messages.created_at')
->join('message_user','messages.id','=','message_user.message_id')
->where("messages.sender",'=',$request->user()->id)
->whereNotIn('message_user.user_id', $subquery)
->union( $buddylist)
->groupBy('sender')
->groupBy('user_id')
->orderBy('created_at','desc')
->get();
If you have another column named 'receiver_id' what you could do is:
$query="select * from messages WHERE sender_id='user_id' or receiver_id='user_id' ORDER BY created_at asc";
I have the project that allows to rate a company in many aspects. The following diagram could help you to understand the relations in my database. Of course, I have deleted from the scheme the fields, that are not important in the context of my problem.
Currently, in my repository class of the Company entity, I am searching for companies using QueryBuilder and returning an instance of \Doctrine\ORM\Tools\Pagination\Paginator.
The below code is responsible for fetching companies:
public function search(CompanySearchQuery $command): Paginator
{
$qb = $this->createQueryBuilder('c')
->setFirstResult($command->getOffset())
->setMaxResults($command->getMaxResults())
->orderBy('c.name', 'ASC');
... plus extra "where" conditions
return new Paginator($qb, true);
}
I wonder how I can attach the average score to each company using QueryBuilder and Paginator.
Here is the native SQL that allows me to get data I need:
SELECT
c.id,
c.name,
AVG(o2.score) as score
FROM
company c
LEFT JOIN
opinion o ON c.id = o.company_id
LEFT JOIN
opinion_scope o2 ON o.id = o2.opinion_id
GROUP BY
c.id
My question is: Is it possible to add averageScore property to the Company class and map it from QueryBuilder result?
I tried to rewrite my SQL query to use with the existing code:
$qb = $this->createQueryBuilder('c')
->select('c', 'AVG(s.score)')
->leftJoin('c.opinions', 'o')
->leftJoin('o.scopes', 's')
->groupBy('c.id')
->setFirstResult($command->getOffset())
->setMaxResults($command->getMaxResults())
->orderBy('c.name', 'ASC')
;
With the above code I get database exception as following:
SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #14 of
SELECT list is not in GROUP BY clause and contains nonaggregated column
'database.o1_.score' which is not functionally dependent on columns in GROUP BY
clause; this is incompatible with sql_mode=only_full_group_by").
The SQL query that is executed for the above QueryBuilder is:
SELECT
DISTINCT id_8
FROM
(
SELECT
DISTINCT id_8,
name_9
FROM
(
SELECT
c0_.updated_at AS updated_at_0,
c0_.description AS description_1,
c0_.website AS website_2,
c0_.email AS email_3,
c0_.phone AS phone_4,
c0_.street AS street_5,
c0_.postal_code AS postal_code_6,
c0_.city AS city_7,
c0_.id AS id_8,
c0_.name AS name_9,
c0_.slug AS slug_10,
c0_.created_at AS created_at_11,
AVG(o1_.score) AS sclr_12,
o1_.score AS score_13,
o1_.opinion_id AS opinion_id_14,
o1_.type_id AS type_id_15
FROM
company c0_
LEFT JOIN opinion o2_ ON c0_.id = o2_.company_id
LEFT JOIN opinion_scope o1_ ON o2_.id = o1_.opinion_id
GROUP BY
c0_.id
) dctrn_result_inner
ORDER BY
name_9 ASC
) dctrn_result
LIMIT
2 OFFSET 0
I do not understand why Doctrine adds the following fragment:
o1_.score AS score_13,
o1_.opinion_id AS opinion_id_14,
o1_.type_id AS type_id_15
The issue seems to be that you're trying to select every column from 'c', which is your resulting table from performing two LEFT JOINs. Instead, you need to be specifying a from clause for the company table:
$qb = $this->createQueryBuilder()
->select('c', 'AVG(s.score)')
->from('company', 'c')
->leftJoin('c.opinions', 'o')
->leftJoin('o.scopes', 's')
->groupBy('c.id')
->setFirstResult($command->getOffset())
->setMaxResults($command->getMaxResults())
->orderBy('c.name', 'ASC')
;
This will avoid including o1.score is your returned columns, which is what that error is referencing
Running the following MySQL Query and am getting this error:
database error Unknown column 'qd.ItemListID' in 'on clause'
SELECT
IFNULL(hqp.IsActive, qd.ItemName) AS Item_Name, DATE_FORMAT(IFNULL(hqp.SalesDate, qd.SalesDate), '%m-%d-%Y') AS effectDate, IFNULL(hqp.NoBid, qd.NoBid) AS noBid, IFNULL(hqp.VendorName, qd.VendorName) AS vendor, IFNULL(hqp.Source, qd.Source) AS source, IFNULL(hqp.Type, qd.Type) AS type, IFNULL(hqp.Cost, qd.PurchaseCost) AS cost, IFNULL(hqp.Price, qd.SalesPrice) AS price, IFNULL(hqp.ConditionCode, '') AS conditionCode, qi.UnitOfMeasureSetRef_FullName AS uom
FROM wp_quantum_data AS qd, wp_hunter_quote_parts AS hqp
LEFT JOIN wp_quickbook_items AS qi ON (qi.ListID = IFNULL(qd.ItemListID, hqp.Item_ListID))
WHERE qd.IsActive = 1 || hqp.IsActive = 1
GROUP BY Item_Name
ORDER BY Item_Name ASC
The column exists in the wp_quantum_data table so I can't explain why this error is occurring. I've tried renaming the column in phpmyadmin by typing the column name in and saving the column structure, but it is still saying that the column doesn't exist.
The problem is that you're mixing the archaic implicit JOIN syntax with LEFT JOIN. The LEFT JOIN only combines with the table immediately before it, which is wp_hunter_quote_parts; you can't refer to columns in wp_quantum_data in the ON clause.
You should get out of the habit of using implicit joins, and use explicit JOIN clauses for everything.
You also seem to have your joins in the wrong order. Since the row can be missing in wp_hunter_quote_parts, that's the table you should LEFT JOIN with.
SELECT
IFNULL(hqp.IsActive, qd.ItemName) AS Item_Name, DATE_FORMAT(IFNULL(hqp.SalesDate, qd.SalesDate), '%m-%d-%Y') AS effectDate, IFNULL(hqp.NoBid, qd.NoBid) AS noBid, IFNULL(hqp.VendorName, qd.VendorName) AS vendor, IFNULL(hqp.Source, qd.Source) AS source, IFNULL(hqp.Type, qd.Type) AS type, IFNULL(hqp.Cost, qd.PurchaseCost) AS cost, IFNULL(hqp.Price, qd.SalesPrice) AS price, IFNULL(hqp.ConditionCode, '') AS conditionCode, qi.UnitOfMeasureSetRef_FullName AS uom
FROM wp_quantum_data AS qd
LEFT JOIN wp_quickbook_items AS qi ON qi.ListID = qd.ItemListID
LEFT JOIN wp_hunter_quote_parts AS hqp ON qi.ListID = hqp.ItemListID AND hqp.IsActive = 1
WHERE qd.IsActive = 1
GROUP BY Item_Name
ORDER BY Item_Name ASC
I'm using Symfony2 with Doctrine 2 and i'm creating a Query for the Pagerfanta Bundle for Symfony 2.
The Query is the following:
$qb = $this->createQueryBuilder('t')
->select()
->join('t.pois', 'p');
$qb->groupBy('t.id');
$qb->addOrderBy('count(case when p.image = 1 then 1 else null end)', 'DESC');
Which will give out the following Query:
SELECT t FROM Bundle\Entity\Turn t INNER JOIN t.pois p GROUP BY t.id ORDER BY count(case when p.image = 1 then 1 else null end) DESC
I also created a MySQL Query first so i can rebuild it in Doctrine 2 which looks like this:
SELECT *
FROM `turn`
LEFT JOIN (
poi
) ON ( turn.id = poi.turn_id )
GROUP BY turn.id
ORDER BY count( case when poi.image = 1 then 1 else null end) DESC;
This native Query works perfectly fine, tested in phpmyadmin.
But the Doctrine 2 Query throwes this exeptions:
Twig_Error_Runtime: An exception has been thrown during the rendering of a template ("[Syntax Error] line 0, col 115: Error: Expected end of string, got '('") in Bundle:Admin:showTurnsFiltered.html.twig at line 64.
QueryException: [Syntax Error] line 0, col 115: Error: Expected end of string, got '('
What am i doing wrong? Or is the Pagerfanta bundle not able to work with this Query?
I fixed this by adding a column to the turn Entity (count_poi) and filling it via native SQL.
After that the Query is the following:
SELECT *
FROM `turn`
ORDER BY t.count_poi DESC;
BUT it's just a workaround, i'm not happy with it, but it works for now