Custom SQL: nodereference joins and latest VID
Question
I'm having a heck of a time constructing a custom SQL query. The query has multiple nodereferences and needs to return the latest node revision. I understand joins pretty well, but for some reason the added complexity of returning the latest revision is tripping me up.
I would prefer to go this route over creating views and executing them programmatically, just because of the complexity of the WHERE
clauses.
I've tried translating the output of an equivalent View, but the prefixing that Views tacks on is making it a huge chore to comprehend. My instinct is that it shouldn't need that many joins either.
Would love to see a generic structure that people might start with, or for conversation's sake here's a massively simplified version of what I'm working with. This version is in a bit of flux, I think I have the latest revision covered but now person1Name, person2Name aren't returning anything.
SELECT event.nid AS eventnid,
event.field_event_date_value AS date,
event.field_event_person1_nid AS person1Nid,
person1.field_person_name_value AS person1Name,
event.field_event_person2_nid AS person2Nid,
person2.field_person_name_value AS person2Name,
FROM {node} n
LEFT JOIN {content_type_event} event
ON n.vid = event.vid
LEFT JOIN {node} refevent
ON event.vid = refevent.nid
LEFT JOIN {content_type_person} person1
ON refevent.vid = person1.nid
LEFT JOIN {content_type_person} person2
ON refevent.vid = person2.nid
Solution
LEFT JOIN {node} refevent
ON event.vid = refevent.nid
LEFT JOIN {content_type_person} person1
ON refevent.vid = person1.nid
LEFT JOIN {content_type_person} person2
ON refevent.vid = person2.nid
This looks wrong. Instead, you probably want to use event.field_event_person1_nid and 2 instead of refevent.vid. The additional join of node shouldn't be necessary, you already have node as the main table.
The query still returns something because you are using LEFT JOIN. Since I assume that these fields are required and/or you only want those which are filled, you should just use JOIN. LEFT JOIN means that the main table is returned even if there is no matching row in the joined table.
The same is true for the content_type_event table. No need for a LEFT JOIN. That is just what views does by default unless you specify that the relationship is required.