SQL COUNT () / LEFT JOIN? - PullRequest
       8

SQL COUNT () / LEFT JOIN?

8 голосов
/ 02 декабря 2010

У меня есть три таблицы: звонки, вложения и заметки, и я хочу отобразить все, что находится в таблице звонков, а также показать, есть ли у звонка вложения и есть ли у звонка заметки. - определив, есть ли вложение или запись заметки с call_id в ней. Там могут быть заметки и вложения, или их не может быть, но мне нужно знать.

Структура таблиц:

звонки:

call_id  |  title  |  description  

принадлежности:

attach_id  |  attach_name  |  call_id  

Примечания:

note_id  |  note_text  |  call_id  

Если я напишу:

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

, чтобы дать мне список всех звонков и количество вложений.

Как я также могу добавить в столбце с количеством заметок или столбец, который указывает, что есть заметки?

Есть идеи?

Спасибо.

Ответы [ 6 ]

18 голосов
/ 02 декабря 2010

Для счета

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

Или для существования (будет более эффективным, если это все, что вам нужно)

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
1 голос
/ 02 декабря 2010
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

Если идентификатор вызова присутствует на полях 4 или 5, вы знаете, что у вас есть вложение или примечание

Если вам нужно указать номер вложения или примечание, посмотрите другие ответы, посмотрите на AtaTheDevпочта.

0 голосов
/ 18 декабря 2017

Я использовал этот простой запрос.Этот запрос позволяет легко использовать столбцы основных таблиц без группировки по.

   Select StudentName,FatherName,MotherName,DOB,t.count  from Student
   left JOIN
   (
    Select StudentAttendance.StudentID,  count(IsPresent) as count 
    from StudentAttendance
    group by StudentID, IsPresent
   ) as t    
  ON   t.StudentID=Student.StudentID
0 голосов
/ 30 августа 2016

Это также работает:

SELECT 
    cl.*,
    (SELECT count(1) FROM attachments AS at WHERE at.call_id = cl.id) as num_attachments,
    (SELECT count(1) FROM notes AS nt WHERE nt.call_id = cl.id) as num_notes,
FROM calls AS cl
0 голосов
/ 02 декабря 2010

Я думаю, что это должно быть что-то вроде этого

SELECT c.call_id, title, description, count(distinct attach_id) , count(distinct note_id) <br> FROM calls c <br> LEFT JOIN attachments a ON c.call_id = a.call_id <br> LEFT JOIN notes n ON n.call_id = a.call_id <br> GROUP BY c.call_id,title,description<br>

0 голосов
/ 02 декабря 2010

Использовать distinct в счетах

Вы должны использовать разные в подсчетах, потому что ваши группы выросли на две разные сущности. Таким образом, вы должны рассчитывать только отдельные значения каждого. Этот следующий запрос вернет оба значения, а также значения bit, есть ли вложения и примечания.

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
...