Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL COUNT() / LEFT JOIN?

I have three tables: calls, attachments and notes and I want to display everything that's in the calls table, but also display whether a call has attachments and whether the call has notes. - by determining if there is an attachment or note record with a call_id in it. There could be notes and attachments, or there may not be but I would need to know.

Tables structure:

calls:

call_id  |  title  |  description  

attachments:

attach_id  |  attach_name  |  call_id  

notes:

note_id  |  note_text  |  call_id  

If I write:

SELECT c.call_id
     , title
     , description
     , count(attach_id) 
FROM calls c 
LEFT JOIN attachments a ON c.call_id = a.call_id 
GROUP BY c.call_id
       , title
       , description

to give me a list of all calls and the number of attachments.

How can I also add in a column with the number of notes or a column which indicates that there is notes?

Any ideas?

Thanks.

like image 649
thegunner Avatar asked Dec 02 '10 10:12

thegunner


People also ask

Can LEFT join increase row COUNT in SQL?

condition.

How do I join two tables and counts in SQL?

To achieve this for multiple tables, use the UNION ALL. select sum(variableName. aliasName) from ( select count(*) as yourAliasName from yourTableName1 UNION ALL select count(*) as yourAliasName from yourTableName2 ) yourVariableName; Let us implement the above syntax.

Can we use COUNT and GROUP BY together?

The use of COUNT() function in conjunction with GROUP BY is useful for characterizing our data under various groupings. A combination of same values (on a column) will be treated as an individual group.

Which is better COUNT (*) or COUNT 1?

The simple answer is no – there is no difference at all. The COUNT(*) function counts the total rows in the table, including the NULL values. The semantics for COUNT(1) differ slightly; we'll discuss them later. However, the results for COUNT(*) and COUNT(1) are identical.


3 Answers

For the count

SELECT 
     c.call_id, 
     title, 
     description, 
     count(DISTINCT attach_id) AS attachment_count , 
     count(DISTINCT note_id)  AS notes_count 
FROM calls c 
LEFT JOIN attachments a ON c.call_id = a.call_id 
LEFT JOIN notes n ON n.call_id = c.call_id 
GROUP BY c.call_id,title,description

Or for existence (will be more efficient if this is all you need)

SELECT 
     c.call_id, 
     title, 
     description, 
     count(attach_id) AS attachment_count , 
     case
        when exists (select * from notes n WHERE n.call_id = c.call_id) then
            cast(1 as bit)
        else
            cast(0 as bit)
    end as notes_exist
FROM calls c 
LEFT JOIN attachments a ON c.call_id = a.call_id 
GROUP BY c.call_id,title,description
like image 180
Martin Smith Avatar answered Oct 24 '22 11:10

Martin Smith


SELECT c.call_id, title, description, a.call_id, n.call_id
FROM calls c 
LEFT JOIN attachments a ON c.call_id = a.call_id 
LEFT JOIN notes n ON c.call_id = n.call_id
GROUP BY c.call_id,title,description, a.call_id, n.call_id

If call id is present in fiels 4 or 5, you know you have an attachement or a note

If you need to number of attachement or note, look at other answers, look at AtaTheDev's post.

like image 23
VdesmedT Avatar answered Oct 24 '22 13:10

VdesmedT


Use distinct in counts

You have to use distinct in counts because your groups have grown by two different entities. So you have to only count distinct values of each. This next query will return both counts as well as bit values whether there are any attachments and notes.

select
    c.call_id, c.title, c.description,
    count(distinct a.attach_id) as attachments_count,
    count(distinct n.note_id) as notes_count,
    /* add these two if you need to */
    case when count(distinct a.attach_id) > 0 then 1 else 0 end as has_attachments,
    case when count(distinct n.note_id) > 0 then 1 else 0 end as has_notes
from calls c
    left join attachments a
    on (a.call_id = c.call_id)
    left join notes n
    on (n.call_id = c.call_id)
group by c.call_id, c.title, c.description
like image 34
Robert Koritnik Avatar answered Oct 24 '22 11:10

Robert Koritnik