DQl JOIN and WHERE - left-join

I'm trying to get query like this:
SELECT * FROM `users` u JOIN clientdetails d WHERE u.id = d.id AND d.staff_id =?
so I wrote DQL:
SELECT u FROM PswAdminBundle:User u JOIN PswAdminBundle:ClientDetails d WHERE d.staffRep=?0
but resulting query is
SELECT * FROM users u0_ INNER JOIN ClientDetails c1_ ON (c1_.staff_id = ?)
May it be because these two tables have 2 relations between them?
In users table I keep all users of app(clients and staff) records representing clients have relation one to one with table clientdetails using id from both tables. In clientdetails I have column staff_id that goes back to user table pointing on record representing staff user.
I'm trying to fetch all clients that are related to staff.

Related

postgresql left join but dont fetch if matching condition found

I have a bit of a complicated scenario. I have two tables, employee and agency. An employee may or may not have an agency, but if an employee has an agency I want the select clause to check another condition on the agency, but if the employee does not have an agency its fine I want to fetch the employee. I'm not sure how to write the select statement for this. This is what I have come up with so far
select * from employee e left join
agency a on a.id = e.agencyID and a.valid = true;
However the problem with this is that it fetches both employees without agencies which is fine, but it also fetches employees with agencies where a.valid = false. The only option I can think of is to do an union but I'm looking for something more simpler.
A UNION could actually be the solution that performs best, but you can write the query without UNION like this:
select *
from employee e
left join agency a
on a.id = e.agencyID
where coalesce(a.valid, true);
That will accept agencies where valid IS NULL, that is, result rows where the agency part was substituted with NULLs by the outer join.
You want except the condition that both table match(agency.id = employee.agencyID) and also agency.id is false. The following query will express the condition.
SELECT
e.*,
a.*
FROM
employee e
LEFT JOIN agency a ON a.id = e.agencyID
WHERE
NOT EXISTS (
SELECT
1
FROM
agency
WHERE
a.id = e.agencyID
AND a.valid IS FALSE)
ORDER BY
e.id;

Join two postgresql queries

I have the following query
SELECT role_uuid FROM users WHERE email = 'email#domain.com'
I also have a roles table the following fields:
uuid
name
created_at
I'm hoping to have 1 query that gives lets me select the role by email and get the name and created_at field from the roles table.
I've tried things like this but I can't quite figure it out.
SELECT *
FROM ( SELECT * FROM users WHERE email = 'email#domain.com') AS A
JOIN ( SELECT * FROM roles WHERE uuid = A.role_uuid) AS B
WHERE A.role_uuid = B.uuid
You JOIN the two tables which gives you a table with all the fields from both source tables. Then you use WHERE to filter and SELECT to specify the fields that you want to be returned.
SELECT r.name, r.created_at
FROM users u JOIN roles r ON (u.role_uuid = r.uuid)
WHERE u.email = 'email#domain.com'
If you run into naming conflicts because of fields from both tables sharing the same name you can use AS to define fieldnames for the output columns:
SELECT r.name AS rolename, u.name AS username, r.created_at
FROM users u JOIN roles r ON (u.role_uuid = r.uuid)
WHERE u.email = 'email#domain.com'

Postgres Query to join two tables

I have two tables in Postgres database. In each table there is a column which represent same number. I have tried few join queries to join both tables with similar column numbers but none of them are giving me the expected output.
user_id column from Table 1 is equal to Id column in Table 2
How can join these two tables?
I have tried below and some other queries as well but it didn't get what I wanted
SELECT members.access_level, members.user_id FROM members INNER JOIN users ON members.user_id = users.id;
Tables columns looks like below,
Members table
id |access_level |source_id |user_id |type
Users Table
id |email |name |username
Query output should look as below:
username |name |email |access_level
SELECT u.username
, u.name
, u.email
, m.access_level
FROM users u
JOIN members m ON (u.id = m.user_id)
;
If you want users that are not included in the members table you can join with a LEFT JOIN
To address your question asked in the comments I believe you'd be looking for something like the following:
UPDATE members SET access_level = 'dev' WHERE access_level = '30';
This is assuming that the column is already of type text. Otherwise, you'll need to change the data type first using the following:
ALTER TABLE members
ALTER access_level SET DATA TYPE text;
SELECT users.*, members.user_id, members.acces_level
FROM members
LEFT JOIN users
WHERE users.id = members.user_id

Complex insert based on few subqueries

I have following tables:
Posts: id, CategoryId
PostAssociations: PostId FK Posts(id), AssociatedPostId FK Posts(id)
So each post may have many other posts as associated posts.
What I need is:
For each post P that does not have any associated posts yet, add 4 random associated posts from the same category (excluding post P - it should not be associated to himself).
So far I have
# SELECT Posts that don't have any associated posts yet
SELECT p.id
FROM "Posts" p
LEFT OUTER JOIN "PostAssociations" pa ON pa."PostId" = p.id
WHERE pa."PostId" IS NULL
And:
# SELECT 4 random posts from given category and excluding given id
SELECT id
FROM "Posts" p2
WHERE p2."CategoryId" = ? AND p2.id != ?
ORDER BY RANDOM()
LIMIT 4
I need query like this:
INSERT INTO "PostAssociations" VALUES ...
SQL fiddle with explanation what I need: http://sqlfiddle.com/#!2/6ba735/5
As you tagged the post with postgresql-9.3 I guess using LATERALto apply the random id generating query over all ids that are missing associations should work. (This should be functionally similar to using OUTER APPLYwith MS SQL for instance).
Sample SQL Fiddle (showing before, insert and after).
INSERT INTO PostAssociations
SELECT
p.id, rand.id rand
FROM Posts p
LEFT OUTER JOIN PostAssociations pa ON pa.PostId = p.id
LEFT JOIN LATERAL
(
SELECT id
FROM Posts
WHERE CategoryId = p.categoryid AND id != p.id
ORDER BY RANDOM()
LIMIT 4) AS rand ON TRUE
WHERE pa.PostId IS NULL;
I can't claim to be an expert with Postgresql so it's quite possible the query can be improved.

Get Greatest date across multiple columns with entity framework

I have three entities: Group, Activity, and Comment. Each entity is represented in the db as a table. A Group has many Activities, and an Activity has many comments. Each entity has a CreatedDate field. I need to query for all groups + the CreatedDate of the most recent entity created on that Group's object graph.
I've constructed a sql query that gives me what I need, but I'm not sure how to do this in entity framework. Specifically this line: (SELECT MAX(X)
FROM (VALUES (g.CreatedDate), (a.CreatedDate), (c.CreatedDate)) Thanks in advance for your help. Here's the full query:
WITH GroupWithLastActivityDate AS (
SELECT DISTINCT
g.Id
,g.GroupName
,g.GroupDescription
,g.CreatedDate
,g.ApartmentComplexId
,(SELECT MAX(X)
FROM (VALUES (g.CreatedDate), (a.CreatedDate), (c.CreatedDate)) AS AllDates(X)) AS LastActivityDate
FROM Groups g
LEFT OUTER JOIN Activities a
on g.Id = a.GroupId
LEFT OUTER JOIN Comments c
on a.Id = c.ActivityId
WHERE g.IsActive = 1
)
SELECT
GroupId = g.Id
,g.GroupName
,g.GroupDescription
,g.ApartmentComplexId
,NumberOfActivities = COUNT(DISTINCT a.Id)
,g.CreatedDate
,LastActivityDate = Max(g.LastActivityDate)
FROM GroupWithLastActivityDate g
INNER JOIN Activities a
on g.Id = a.GroupId
WHERE a.IsActive = 1
GROUP BY g.Id
,g.GroupName
,g.GroupDescription
,g.CreatedDate
,g.ApartmentComplexId
I should add that for now I've constructed a view with this query (plus some other stuff) which I'm querying with a SqlQuery.