[thelist] Stuck on SQL
r937
rudy at r937.com
Fri Jul 24 09:25:11 CDT 2009
fred, first of all, thanks for the kind words
in the original query that you posted --
SELECT civicrm_contact.id
, COUNT(civicrm_entity_tag.tag_id)
FROM civicrm_contact
LEFT OUTER
JOIN civicrm_entity_tag
ON civicrm_entity_tag.contact_id = civicrm_contact.id
LEFT OUTER
JOIN civicrm_tag
ON civicrm_tag.id = civicrm_entity_tag.tag_id
GROUP
BY civicrm_contact.id;
you can actually remove the second join and get the same results
;o)
so if this query produces the results you want, then we must leave this
SELECT clause as is, because it counts the tags the contacts ~do~ have, and
we want to keep showing that
the qualification of which contacts survive the new filter criterion can
easily be done with a subquery in the WHERE clause
chris nailed it when he said "How about counting the number of tags, then
using the HAVING clause to just select those with 0 tags"
here's his query --
SELECT civicrm_contact.id
, COUNT(civicrm_entity_tag.tag_id)
FROM civicrm_contact
LEFT OUTER
JOIN civicrm_entity_tag
ON civicrm_entity_tag.contact_id = civicrm_contact.id
LEFT OUTER
JOIN civicrm_tag
ON civicrm_tag.id = civicrm_entity_tag.tag_id
WHERE civicrm_tag.name LIKE "%Primary%"
OR civicrm_tag.name LIKE "%Secondary%"
GROUP
BY civicrm_contact.id
HAVING COUNT(civicrm_entity_tag.tag_id) = 0
chris, you could've omitted COUNT(civicrm_entity_tag.tag_id) from the SELECT
clause, because you know what it's going to be, right?
note that here we do have to extend the joins to the tags table, in order to
perform the test on the tag name
however, WHERE is wrong, it has to be AND
this query will identify all of those contacts for whom you want results
returned by the original query, so we push it down a level of nesting, and
make it a subquery in the WHERE clause...
SELECT civicrm_contact.id
, COUNT(civicrm_entity_tag.tag_id)
FROM civicrm_contact
LEFT OUTER
JOIN civicrm_entity_tag
ON civicrm_entity_tag.contact_id = civicrm_contact.id
WHERE civicrm_contact.id IN
( SELECT civicrm_contact.id
FROM civicrm_contact
LEFT OUTER
JOIN civicrm_entity_tag
ON civicrm_entity_tag.contact_id = civicrm_contact.id
LEFT OUTER
JOIN civicrm_tag
ON civicrm_tag.id = civicrm_entity_tag.tag_id
AND (
civicrm_tag.name LIKE "%Primary%"
OR civicrm_tag.name LIKE "%Secondary%"
)
GROUP
BY civicrm_contact.id
HAVING COUNT(civicrm_entity_tag.tag_id) = 0 )
GROUP
BY civicrm_contact.id
let me know if that works
;o)
rudy
http://simply-sql.com/
More information about the thelist
mailing list