2015-02-25 1 views
-1

Я работаю над запросом, чтобы вернуть, сколько активистов добровольно вызвались в этом году командой более одного раза; Я получил его на работу в качестве отдельного запроса:Как использовать HAVING в подзапросе как часть инструкции выбора

SELECT Activists.team, COUNT(id) AS Activists 
    FROM 
    (
     SELECT e.id, v.team, 
     COUNT(CASE WHEN (e.status="Completed" AND right(e.date,2)="15") THEN e.id END) AS count 
     FROM actiontable e 
     LEFT JOIN persontable v ON v.id = e.id 
     GROUP BY e.id, v.team 
     HAVING (count > 1) 
    ) AS Activists 
    GROUP BY Activists.team; 

Но я не могу вполне понять, как заставить его работать в более SELECT заявлении. Проблема я бег в том, что у меня есть много других (более простой) части запроса, чтобы вернуть вещи команды также в SELECT заявлении как:

COUNT(DISTINCT CASE WHEN v.WillCanvass = "X" THEN v.id END) 

Так, очевидно, я не могу иметь HAVING (count > 1) части запроса для активистов, потому что тогда это повлияет на все остальные части моего заявления SELECT - так что мне нужен подзапрос выше, чтобы затронуть только ту часть, где я работаю.

Я сделал SQL Fiddle с образцом схемой, чтобы помочь с вышеупомянутым запросом, который работает - но в идеале хотелось бы, чтобы получить выходной сигнал, который выглядит примерно так, где Activists подзапрос не влияет на WillCanvass колонки (даже если Я составил цифры ниже):

Team Activists WillCanvass 
Team A 2   2 
Team B 8   5 
Team C 7   3 

Надеюсь, что имеет смысл - спасибо!


EDIT

Мой лучший выстрел на то, что я хочу - хотя запрос дает мне ошибки - выглядит следующим образом:

SELECT a.team as team, 
    COUNT(v.*) as activists, 
    SUM(CASE WHEN v.WillCanvass = "X" THEN 1 ELSE 0 END) as WillCanvass 
FROM 
persontable v 
left join 
(
    SELECT e.id, 
     v.team, 
     v.WillCanvass, 
     COUNT(*) as count 
    FROM actiontable e 
    LEFT JOIN persontable v ON v.id = e.id 
    WHERE e.status="Completed" AND right(e.date,2)="15" 
    GROUP BY e.id 
    HAVING (count > 1)) as a 
     GROUP BY team; 

Там же обновленный SQL скрипку его here ,

+0

где ссылка на ** ваш ** sqlfiddle ??? – Alex

+0

@Alex Извините, это встроено: [http://sqlfiddle.com/#!2/8f4e1d/2](http://sqlfiddle.com/#!2/8f4e1d/2) – Ryan

+0

так что вы выполнили мой запрос там ? – Alex

ответ

0

Я получил его - спасибо, что помог мне добраться туда, но это совсем не то, что было выше. Я должен был взять пункт HAVING полностью, чтобы иметь первую часть SELECT заявления (WillCanvass) быть полностью независимым от actiontable его части:

SELECT a.team as team, 
    COUNT(case when a.X > 1 then a.id else null end) as activists, 
    SUM(CASE WHEN a.WillCanvass = "X" THEN 1 ELSE 0 END) as WillCanvass 
FROM (
    SELECT v.id, 
     v.team, 
     v.WillCanvass, 
     COUNT(case when e.status="Completed" AND right(e.date,2)="15" then e.id else null end) as X 
    FROM actiontable e 
    RIGHT JOIN persontable v ON v.id = e.id 
    GROUP BY v.id, v.team, v.WillCanvass 
) as a 
GROUP BY team; 

И вот новый SQL Fiddle, чтобы увидеть, как это работает.

0

попробовать этот способ:

http://sqlfiddle.com/#!2/e186da/5

SELECT v.team as team, 
     SUM(CASE WHEN (e.status="Completed" AND YEAR(e.date)="2015") THEN 1 ELSE 0 END) AS count 
     FROM actiontable e 
     LEFT JOIN persontable v ON v.id = e.id 
     GROUP BY v.team 
     HAVING (count > 1); 


SELECT v.team as team, 
     SUM(CASE WHEN (e.status="Completed" AND YEAR(e.date)="2015") THEN 1 ELSE 0 END) AS count, 
     SUM(CASE WHEN (v.WillCanvass='X') THEN 1 ELSE 0 END) AS WillCanvass 
     FROM actiontable e 
     LEFT JOIN persontable v ON v.id = e.id 
     GROUP BY v.team 
+0

Спасибо! Как я сказал выше, выходные номера составлены - так что им не обязательно соответствовать; он должен просто выглядеть похожим на это. И ваш второй оператор SELECT выше в точности соответствует тому, что я хочу, чтобы результат выглядел, за исключением того, что он не пропускал 'HAVING (count> 1)' из первого оператора SELECT' - это та часть, с которой у меня возникли проблемы с , Могут ли эти два сочетаться? – Ryan

+0

просто используйте последний, если вам нужно – Alex

+0

Второй будет замечательным - но он учитывает завершенные действия 2015 года, как один, когда весь смысл того, что я не могу понять, заключается в том, что мне нужно считать только счет завершен 2015, которые происходят только один раз - следовательно, 'HAVING (count> 1)' часть запроса. Хотя я не могу сделать это для всего запроса, потому что тогда он также сузил бы людей WillCanvass. – Ryan

1

Не уверен, что именно то, что вы пытаетесь достичь. Сначала я получаю список активистов с правильными критериями, а затем команду GROUP BY.

SELECT a.team as team, 
    COUNT(*) as activists, 
    SUM(CASE WHEN a.WillCanvass = "X" THEN 1 ELSE 0 END) as WillCanvass 
FROM (
    SELECT e.id, 
     v.team, 
     v.WillCanvass, 
     COUNT(*) as count 
    FROM actiontable e 
    LEFT JOIN persontable v ON v.id = e.id 
    WHERE e.status="Completed" AND right(e.date,2)="15" 
    GROUP BY e.id 
    HAVING (count > 1)) as a 
GROUP BY team 
+0

Я думаю, что это именно то, что мне нужно - спасибо! Но я собираюсь проверить это немного против моего кода, отличного от примера. Я пытался достичь 'HAVING (count> 1)' внутри подзапроса вместо всего запроса, но я все время сталкивался с ошибками. – Ryan

+0

Это действительно близко, я думаю, но я понял, что 'WillCanvass' исходит от' a', что означает, что он сужает людей, помеченных «WillCavass» _ «X» _ теми же критериями, что и ' a' table - это означает, что люди 'WillCanvass' также должны иметь более одного вхождения в' actiontable' для подсчета, но я хочу, чтобы они были полностью разделены, так что все, отмеченные 'WillCanvass', считаются независимо от того, что связано с 'actiontable'. Это возможно? – Ryan

+0

Еще один способ сказать, что очевидное исправление (если оно сработало) будет просто заменять 'a.WillCanvass' на' v.WillCanvass' - но, очевидно, способ создания этого запроса, SQL не понимает 'v.WillCanvass' в списке полей. – Ryan