How to left join in query builder without entity in doctrine zend - zend-framework

Hi I have M:M relationship between two tables, Contacts and Tags and their M:M table is called Contacts_Tags:
Contacts
------------
ID
Name
Tags
-----------
ID
Name
Contacts_Tags
--------------
Contact_ID
Tag_ID
I have entities for Contacts called Contact and for Tags called Tag but not for Contacts_Tags table.
I want to left join in query builder
$queryBuilder = $this->entityManager->getRepository(Contact::class)->createQueryBuilder("o")->select("o");
$queryBuilder->leftJoin(//here, "et", "WITH", "et.Contact_ID = o.ID")
->leftJoin(Tag::class, "t", "WITH", "t.ID = et.Tag_ID")
;
But I cannot figure out how to add it. I tried documentations but it says to add Entity when I add entity of ContactTag it throws error that entity should have primary key.
Any idea?

To do left join :
$queryBuilder->join(table, condition, columns, $queryBuilder::JOIN_LEFT);
with :
table is the name of a table or another Select or array [alias => table]
condition is a string (the same as in Sql language)
columns is an array like [alias => column_name, ...] or [column_name, ...], may be empty
$queryBuilder is a Select, can be replaced by \Zend\Sql\Select::JOIN_LEFT

Related

Renaming all existing attributes in an array of Json objects

I work with Postgres db.
For example - there is a table
CREATE TABLE public.json_objects(id serial primary key, objects text);
it stores such an arrays of json
INSERT INTO public.json_objects (objects) VALUES ('[{"name":"Ivan"}]'), ('[{"name":"Petr"}, "surname":"Petrov"}]'), ('[{"form":"OOO"}, {"city":"Kizema"}]');
How can I replace the attribute "name" with "first name" or "surname" with "second name" everywhere?
I am using update with the select - subquery.
In this case, a replacement will occur, but if the attribute does not exist in the json object, then it will be added to the json with a null value (and this should not be)
WITH updated_table AS (SELECT id, jsonb_agg(new_field_json) as new_fields_json
FROM (SELECT id, jsonb_array_elements(json_objects.objects::jsonb) - 'name' || jsonb_build_object('first name', jsonb_array_elements(json_objects.objects::jsonb) -> 'name') new_field_json FROM public.json_objects) r group by id) UPDATE public.json_objects SET objects = updated_table.new_fields_json FROM updated_table where json_objects.id = updated_table.id
This seems to be a single operation, so you can just use the regexp_replace function to replace the key
update table_1 set objects = regexp_replace(objects, '(\"name"+)', '"first name"');
update table_1 set objects = regexp_replace(objects, '(\"surname"+)', '"second name"')
Demo in dbfiddle

Building a jsonb object without using subquery in postgresql 12

I have a table called users that has a jsonb column called 'history'. This is an array of objects, one of the elements is called uid which is the id of the person visiting the page as follows:
[ {"ip":"...","uid":2} , {"ip":"...","uid":4} , ... ]
I'm running a query that appends the jsonb object with the field uname to make understanding who 'uid' is a bit easier which will produce:
[ {"ip":"...","uid":2,"uname":"bob"} , {"ip":"...","uid":4,"uname":"dave"} , ... ]
I'm currently doing this using the following query (say, where uid=2):
SELECT json_agg(history2||jsonb_build_object('uname',uname::text)) FROM
(SELECT jsonb_array_elements(history) AS history2 FROM users WHERE uid=2) AS table1
LEFT JOIN users AS table2 ON history2->>'uid'=table2.uid
I'm using the subquery to return a table of json objects that's then joined to the user table again to get the username.
My question is: Is there a way of doing this without having the subquery? I've read that lateral joins could be used but all my attempts at this don't seem to work.
Thanks in advance.
You can move jsonb_array_elements into the FROM clause with an outer join:
SELECT jsonb_agg(h.item||jsonb_build_object('uname', u.uname))
FROM users u
LEFT JOIN jsonb_array_elements(u.history) as h(item) on h.item ->> 'uid' = u.uid::text
WHERE u.uid = 2

Postgresql easiest way to replace ID's with Names

In Postgresql:
Say I have a table Dogs:
SELECT * FROM "Dogs"
...
Name OwnerID
'Pooch' 'OWR14'
'Sparky' 'OWR12'
'Pooch' 'OWR17'
And a table Owners:
SELECT * FROM "Owners"
...
ID Name
'OWR14' 'Peter'
'OWR12' 'Jack'
'OWR17' 'Mary'
What is the fastest/easiest way to replace the OwnerID field with the Name values from the Owner table?
My fastest way:
SELECT "Dogs"."Name", "Owners"."Name" AS "Owner"
FROM "Dogs"
LEFT JOIN "Owners" ON "Dogs"."OwnerID" = "Owners"."ID"
...
Name Owner
'Pooch' 'Peter'
'Sparky' 'Jack'
'Pooch' 'Mary'
looking to your sample could be an upodate with join
UPDATE Dogs
SET Dogs.OwnerID = Owners.Name
FROM Owners
WHERE Dogs.OwnerID = Owners.id;
Otherwise if you just need a faster query then be sure you have proper composite index on table Dogs
CREATE INDEX my_idx1 on "Dogs" ("OwnerID", "Name" )
and for table Owners
CREATE INDEX my_idx2 on "Owners" ("ID", "Name" )

Foreign key record in Entity Framework

I have recently started using Entity Framework and have run into a problem.
I have 2 simple tables mapped with Entity Framework in my solution:
Employees:
emp_id INT
first_name VARCHAR
last_name VARCHAR
department INT ( FOREIGN KEY MAPPED TO departments.dept_id )
and
Departments:
dept_id INT
department_name VARCHAR
Using the code below, I want to write to the database.
var record = db.employees.Create();
string test = "test";
record.first_name = test;
record.last_name = test;
record.department = 1;
db.employees.Add(record);
db.SaveChanges();
I get an error the error:
Entities in "'DBContextContainer.employees' participate in the 'employeedepartment' relationship. 0 related 'department' were found. 1 'department' is expected."
at the db.SaveChanges() method. Can someone please explain to me how I could resolve or troubleshoot this?
Update: There is a record in the departments table with a dept_id of 1 and I am still getting the error.
You'll need to add a field to the Departments table first since Departments is the parent table (Employees depend on Departments as per your table structure). You cant add an employee with department that doesn't have a corresponding entry in the Departments table.

JPA: Querying an object and single values from other entity

Is it possible with JPA to query a database to get an entity filled with an additional field belonging to another table/entity?
I have a reservations table holding a foreign key to a record(an entity) in another table pois which has to columns of interest: poiId and poiType.
Instead of having a field ReservationEntity.poi (to finally obtain poi.poiType) I want to have a ReservationEntity.poiId and ReservationEntity.poiType and I wonder if it's possible to achieve this through a NamedQuery:
#NamedQuery(name="ReservationEntity.findByRfId", query="SELECT r, p.poiType FROM ReservationEntity r LEFT JOIN PoiEntity p ON r.poiId = p.poiId WHERE r.rfId = :rfId")
...since you read my question you can imagine that this DOESN'T work. ;-)
Is it possible to do it in such a kind?
Here's the exception:
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'POITYPE' in 'field list'
Error Code: 1054
Call: SELECT reservationId, endTime, notification, poiId, POITYPE, startTime, status, timeZone, tstamp, type FROM reservations WHERE (reservationId = ?)
bind => [1 parameter bound]
Query: ReadObjectQuery(name="ReservationEntity.findById" referenceClass=ReservationEntity sql="SELECT t1.reservationId, t1.authInfo, t1.endTime, t1.evsp, t1.notification, t1.poiId, t1.POITYPE, t1.startTime, t1.status, t1.timeZone, t1.tstamp, t1.type FROM reservations t1 LEFT OUTER JOIN pois t0 ON (t1.poiId = t0.poiId) WHERE (t1.reservationId = ?)")
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:340)
By now I made it work using a database view instead of a table for the #Entity(...) annotation.
Yet I don't have the requirement to update the entity. However, it is possible to update a view as long as only one table' column are modified and an INNER JOIN is used: http://dev.mysql.com/doc/refman/5.6/en/view-updatability.html