am having a problem constructing a query
here is simplified tables structure
3 tables
Event [Event_id , Event_name]
Event_files [Event_id(FK) , File_id(FK)]
Uploaded_Files[File_id , File_type, File_path]
we mainly have 2 file types
image = 2
document = 4
what am trying to do is to get the events along with their images (if they have an image )
am trying to do this with this Query
select e.id, e.name,uf.id as file_id,uf.path
from event e
left join event_file ef on ef.event_id = e.id
left join uploaded_file uf ON ef.file_id = uf.id
i know that i need to apply a condition but each time i do in the where or ON there is always problem with the Query
for example if i apply :
left join uploaded_file uf ON ef.file_id = uf.id AND (uf.type = 2 )
it will still return 2 records for the events that has both image and file one of them with file_path null .
on the other hand if i do the following :
where (uf.id is null OR (uf.id is not null AND uf.type=2))
the events with only files and no image will not be returned any more
is there is solution please ?
thanks in advance
SELECT e.id, e.name, f.file_id AS file_id, f.path
FROM event e
LEFT JOIN
(
SELECT ef.event_id, uf.id AS file_id, uf.path
FROM event_file ef
INNER JOIN uploaded_file uf ON ef.file_id = uf.id AND uf.type = 2
) f ON f.event_id = e.id
This should do (untested.)
The reason you're getting the empty record is because you only specify the uf.type condition on the uploaded_file table, which imposes nothing on the left join for event_file.
Related
I have 3 table (property, facility, property_facility)
Now I want to get all facilities from facility table alone with property data to given property ID.
I tried it with LEFT JOIN as below. But I cannot get all facilities from facility table.
SELECT property_id
, contract_id
, type_id
, location_id
, beds
, ROUND(price,3) as price
, f.facility_id
, f.name
, pf.facility_id
FROM facility f
LEFT JOIN property_facility pf ON pf.facility_id = f.facility_id AND pf.property_id = 6
LEFT JOIN property p USING(property_id)
WHERE p.property_id = 6
Can anybody tell me how I make this query correctly?
Your WHERE clause is filtering out the facilities that do not match. You will need to switch the USING to ON and do:
FROM facility f LEFT JOIN
property_facility pf
ON pf.facility_id = f.facility_id AND
pf.property_id = 6 LEFT JOIN
property p
ON p.property_id = pf.property_id AND p.property_id = 6
You seem to understand the concept, because you are using the same condition for the first JOIN.
Well, actually, the property_id doesn't change. So, you can just remove the WHERE clause and continue with USING if you prefer.
This query is taking between 20-40 seconds to run. I need to speed it up greatly if possible.
SELECT DISTINCT a.category, a.key
FROM system_permissions AS a, system_permission_to_role AS b,
system_user_to_role AS c, system_users AS d
WHERE
(
(
a.system_permission_id=b.system_permission_id
AND (b.system_role_id=c.system_role_id || c.system_role_id = 0)
AND a.system_permission_id NOT IN (
SELECT system_permission_id FROM system_permission_exclusions AS f
WHERE d.system_user_id=f.system_user_id
)
AND c.system_user_id=d.system_user_id
)
OR a.system_permission_id IN (
SELECT system_permission_id
FROM system_permission_inclusions AS g
WHERE d.system_user_id=g.system_user_id
)
)
AND d.ldap_objectguid = '?';
The reason behind doing it this way is that I am creating exclusion and inclusion tables for permissions that fall outside of the standard defined roles, so first I need to exclude ones that are part of the role but exist in the exclusion table, then I need to add ones that are NOT part of their role, but exist in the inclusion table.
I am open to the idea of redesigning the tables also.
Does this work?
SELECT DISTINCT P.category, P.key
FROM system_users U
LEFT OUTER JOIN system_permission_inclusions PI ON PI.system_user_id = U.system_user_id
INNER JOIN system_user_to_role UR ON UR.system_user_id = U.system_user_id
INNER JOIN system_permission_to_role PR ON PR.system_role_id = UR.system_role_id
INNER JOIN system_permissions P ON P.system_permission_id = PR.system_permission_id OR P.system_permission_id = PI.system_permission_id
WHERE U.ldap_objectguid = '?'
AND P.system_permission_id NOT IN (SELECT system_permission_id FROM system_permission_exclusions WHERE system_user_id = U.system_user_id)
I am trying to write a query that uses a LEFT OUTER JOIN on three tables. I have complete the first part to join two tables but I am stuck on intergarting the third table.
What I need is the "Status" field for the NXLHR_Valid to be included in the first query.
Below are my to queries, how would I include the SECOND query into the FIRST query
FIRST QUERY
SELECT NXLHR_SequenceNo_default.SeqNo, NXLHR_SequenceNo_default.SeqHeader, NXLHR_SequenceNo_default.SeqText, NXLHR_Hist.UniqueID, NXLHR_Hist.Room, NXLHR_Hist.Status, NXLHR_Hist.Water, NXLHR_Hist.AuditBy
FROM NXLHR_SequenceNo_default
LEFT OUTER JOIN NXLHR_Hist
ON NXLHR_SequenceNo_default.SeqID = NXLHR_Hist.SeqID
AND NXLHR_Hist.UniqueID = 'NXLHR01031472477564'
WHERE NXLHR_SequenceNo_default.SeqActive = 1
ORDER BY NXLHR_SequenceNo_default.OrderID
SECOND QUERY
SELECT NXLHR_Valid.UniqueID, NXLHR_Valid.Status
FROM NXLHR_Valid
WHERE NXLHR_Valid.UniqueID = 'NXLHR01031472477564'
Any help would be great. Thank you for your time.
SELECT d.SeqNo
, d.SeqHeader
, d.SeqText
, h.UniqueID
, h.Room
, h.Status
, h.Water
, h.AuditBy
, v.Status
FROM NXLHR_SequenceNo_default d
LEFT
JOIN NXLHR_Hist h
ON h.SeqID = d.SeqID
AND h.UniqueID = 'NXLHR01031472477564'
LEFT
JOIN NXLHR_Valid v
ON v.UniqueID = h.UniqueID
WHERE d.SeqActive = 1
ORDER
BY d.OrderID
I'm having trouble with a simple MySQL Query.
Here is the query:
SELECT distinct e.E_CODE, s.S_CODE, p.P_ID, p.P_NAME, p.P_FIRSTNAME, p.P_STATUS, e.E_BOSS, tp.TP_TITLE
from event_participation ep, worker p, type_participation tp, event e, section s
where ep.P_ID = p.P_ID
and s.S_ID = e.S_ID
and ep.TP_ID = tp.TP_ID
and e.E_CODE = ep.E_CODE
The problem is that ep.TP_ID sometimes has a value set to zero while tp.TP_ID has nothing with a zero ID. It's auto-increment and starts at 1 and so on.
The result is obviously that this query does not return records when the ep.TP_ID = 0 and there is no match in tp.TP_ID.
So I'm trying to figure out a way to get those results in there anyway. I was thinking of using a LEFT JOIN statement but couldn't figure out a proper way to insert it into the query.
Any advice on this matter would be greatly appreciated.
First of all, I advice you to use some general type for event_participation records without type; But, unless to take that decision, supposing you want to get all matching records between all tables but also get results with no type, you can use the following query:
SELECT DISTINCT e.E_CODE, s.S_CODE, p.P_ID, p.P_NAME, p.P_FIRSTNAME, p.P_STATUS, e.E_BOSS, tp.TP_TITLE
FROM event_participation ep
JOIN worker p ON (ep.P_ID = p.P_ID)
JOIN event e ON (e.E_CODE = ep.E_CODE)
JOIN section s ON (s.S_ID = e.S_ID)
LEFT JOIN type_participation tp ON (ep.TP_ID = tp.TP_ID)
SELECT DISTINCT e.E_CODE
, s.S_CODE
, p.P_ID
, p.P_NAME
, p.P_FIRSTNAME
, p.P_STATUS
, e.E_BOSS
, tp.TP_TITLE
FROM event_participation ep
JOIN worker p
ON p.P_ID = ep.P_ID
JOIN event e
ON e.E_CODE = ep.E_CODE
JOIN section s
ON s.S_ID = e.S_ID
LEFT
JOIN type_participation tp
ON tp.TP_ID = ep.TP_ID;
I have several tables that I am trying to get some data out of, and I am very close, but cannot quite close the deal.
I have the following tables:
EVENT
USER
FRIEND
USER__FRIEND
EVENT__INVITATION
USER and FRIEND are linked via the USER__FRIEND table (which contains a USER_ID and a FRIEND_ID field)
EVENT__INVITATION links an EVENT with a FRIEND (it has EVENT_ID and INVITEE_ID)
I am trying to get all EVENTS where:
I am the EVENT creator ($myUserID = EVENT.CREATOR_ID)
or I am invited to the event ($myUserID = EVENT__INVITATION.INVITEE_ID)
or one of my FRIENDs is the creator of the EVENT ($myUserID = USER__FRIEND.USER_ID AND EVENT.CREATOR_ID IN (list of my FRIENDs))
or one of my FRIENDs is invited to the EVENT ($myUserID = USER__FRIEND.USER_ID AND EVENT__INVITATION.INVITEE_ID IN (list of my FRIENDs))
There are some other WHERE conditions around other parameters, but I think I can sort those out on my own.
Right now the only way I could get this to work was with a UNION, which I think must be a cop-out, and if I had better chops I could get around using it.
So, the question is, can this be done with a single, inexpensive query that does not use a UNION?
Here is what I have so far, which accomplishes everything except the EVENTs that my FRIENDs are invited to (23 is the passed in userID in this case):
SELECT e.*
FROM event e
LEFT JOIN event__invitation ei ON ei.event_id = e.id
LEFT JOIN user__friend uf ON uf.friend_id = ei.invitee_id
LEFT JOIN friend f ON f.id = uf.friend_id
WHERE (ei.invitee_id = 23 OR e.creator_id = 23 OR uf.user_id = 23 OR f.user_id = e.creator_id)
AND e.start_time >= 1348000000
and this is the query with the UNION:
SELECT e.* FROM event e
INNER JOIN event__invitation ei ON ei.event_id = e.id
INNER JOIN user__friend uf ON uf.friend_id = ei.invitee_id
WHERE (e.creator_id = 23 OR ei.invitee_id = 23 OR uf.user_id = 23)
UNION
SELECT e1.* FROM event e1
WHERE e1.creator_id IN (
SELECT f1.user_id FROM friend f1
INNER JOIN user__friend uf1 ON uf1.friend_id = f1.id
WHERE uf1.user_id = 23
AND f1.user_id IS NOT NULL
);
There is more to the query that makes the use of the UNION undesireable. I have a complex trig calculation that I am doing in the main select, and am ordering the results by that value. I think may mess up the result set.
Thanks for any help!!
How about the following:
-- take only distinct events
SELECT DISTINCT e.*
-- start with the event
FROM event e
-- expand to include all invitees and their user_friend info
LEFT JOIN event__invitation ei
ON ei.event_id = e.id
LEFT JOIN user__friend invitee
ON invitee.friend_id = ei.invitee_id
-- now we join again to user_friend to get the friends of the invitees/the creator
LEFT JOIN user__friend invitedFriend
ON invitedFriend.user_id = invitee.user_id
OR invitedFriend.user_id = e.creator_id
-- finally we match on whether any of these friends of friends are myself
LEFT JOIN friend myselfAsAFriend
ON myselfAsAFriend.id = invitedFriend.friendId
AND myselfAsAFriend.userID = 23
WHERE
(
-- (1) I am the creator of the event
e.creator_id = 23
-- (2) I am invited to the event
OR invitee.user_id = 23
-- (3 and 4) for this join to match a friend of mine must be invited or the creator
OR myselfAsAFriend.id IS NOT NULL
)
AND e.start_time >= 1348000000
I'm not very good at query tuning presently, so I would just give something like this a try and let the optimiser to put its effort in figuring out the best way of getting the results:
SELECT DISTINCT e.*
FROM event e
INNER JOIN event__invitation ei ON ei.event_id = e.id
INNER JOIN (
SELECT friend_id
FROM user__friend
WHERE user_id = $myUserID
UNION ALL
SELECT $myUserID
) u ON u.friend_id IN (e.creator_id, ei.invitee_id)
;
If this doesn't prove efficient enough, you could always go with something like #ChaseMedallion's suggestion, as it may indeed turn out a better one for your case.