2013-08-21 2 views
0

Я пытаюсь найти количество дней, перечисленных человеком, где у них более 100 записей в таблице записей. У этого есть проблема с предложением, но я не уверен, как еще различить подсчеты от человека. Существует также проблема с предложением where, я также попытался поставить «где Count (Recordings.ID)> 100», и это тоже не сработало. Вот то, что я до сих пор:SQL Найти количество записей в день и по пользователю

SELECT Person.FirstName, 
     Person.LastName, 
     Count(Recordings.ID) AS DAYS_ABOVE_100 
FROM Recordings 
JOIN Person ON Recordings.PersonID=Person.ID 
WHERE DAYS_ABOVE_100 > 100 
AND Created BETWEEN '2013-08-01 00:00:00.000' AND '2013-08-21 00:00:00.000' 
GROUP BY Person.FirstName, 
     Person.LastName 
HAVING Count(DISTINCT PersonID), Count(Distinct Datepart(day, created)) 
ORDER BY DAYS_ABOVE_100 DESC 

Пример данных о том, что я хочу получить:

First Last Days_Above_100 
John Doe  5 
Jim Smith 12 

Это означает, что в течение 5 дней в определенный период времени, Джон Доу имел более 100 записи каждый день.

ответ

1

Ради дискретностью, я бы разбить задачу на две части.

Во-первых, выясните, сколько записей каждый человек имеет на один день. Это запрос в выражении общей таблицы (первый оператор select). Затем выберите против общего выражения таблицы, чтобы ограничить строки только теми, которые вам нужны.

with cteRecordingsByDate as 
(
    SELECT Person.FirstName, 
     Person.LastName, 
     cast(created as date) as Whole_date, 
     Count(Recordings.ID) AS Recording_COUNT 
    FROM Recordings 
    JOIN Person ON Recordings.PersonID=Person.ID 
    WHERE Created BETWEEN '2013-08-01 00:00:00.000' AND '2013-08-21 00:00:00.000' 
    GROUP BY Person.FirstName, Person.LastName, cast(created as date) 
) 

select FirstName, LastName, count(*) as Days_Above_100 
from cteRecordingsByDate 
where Recording_COUNT > 100 
order by count(*) desc 
+0

Мне просто нужно было добавить «Group By FirstName, LastName» во второй и последней строках, и это сработало! Спасибо за вашу помощь! – Klay

0

Вы можете считать, что хотите, используя подзапрос. Внутренний запрос подсчитывает количество записей в день. Внешний подзапрос подсчитывает количество дней, которые превышают 100 (и добавляет в информации человека, а):

SELECT p.FirstName, p.LastName, 
     count(*) as DaysOver100 
FROM (select PersonId, cast(Created as Date) as thedate, count(*) as NumRecordings 
     from Recordings r 
     where Created BETWEEN '2013-08-01 00:00:00.000' AND '2013-08-21 00:00:00.000' 
    ) r join 
    Person p 
    ON r.PersonID = p.ID 
WHERE r.NumRecordings > 100 
GROUP BY p.FirstName, p.LastName; 

При этом используется синтаксис SQL Server для преобразования из datetime в date. В других базах данных вы можете использовать trunc(created) или date(created), чтобы извлечь дату из даты и времени.

+0

Я считаю, что ему нужно предложение 'HAVING', чтобы изолировать дни, в которых люди имеют более 100 записей в таблице записей. –

+0

@GoatCO. , , Нажмите. Я понял. Описание в тексте и запросе, похоже, не описывает одну и ту же структуру данных. Я полностью пересмотрел ответ. –

0

Вы должны попробовать это:

SELECT SUBQUERY.FirstName, 
     SUBQUERY.LastName, 
     Count(*) AS DAYS_ABOVE_100 
FROM 
(
    SELECT Person.FirstName, 
      Person.LastName, 
      Count(Recordings.ID) AS COUNT_RECORDINGS 
    FROM Recordings 
    JOIN Person ON Recordings.PersonID=Person.ID 
    WHERE Created BETWEEN '2013-08-01 00:00:00.000' AND 
          '2013-08-21 00:00:00.000' 
    GROUP BY Person.FirstName, 
       Person.LastName, 
       Created 
    HAVING Count(Recordings.ID) > 100 
)SUBQUERY 
GROUP BY SUBQUERY.FirstName, 
      SUBQUERY.LastName 
ORDER BY Count(*) DESC 

Подумайте о том, что имея пункт работает как ИНЕКЕ, но один, который принимает агрегаты, как сумма (source). Ваш запрос имел некоторые ошибки, а именно:

  • Агрегатная в WHERE положение, но где положение не принимают агрегаты.
  • Вы ссылались на совокупность «Count (Recordings.ID)» под этим псевдонимом «DAYS_ABOVE_100» в предложении ORDER BY. Вы не можете получить доступ к столбцу по его псевдониму внутри того же самого выбора, где вы определили этот псевдоним. Столбцы могут быть доступны только по их псевдониму вне запроса, как в ответе Чарльза.

EDIT:

К сожалению, я не заметил, что "на день" часть, отредактированный запрос. Добавлено создано column to Предложение GROUP BY, чтобы получить общее количество записей в день, затем завернуло его в другой запрос, чтобы подсчитать результаты, снова сгруппировав его по первому имени и фамилии.

+0

Это только дает мне общее количество записей для каждого человека за весь период времени. – Klay

0

Я думаю, что это то, что вы после:

SELECT p.FirstName, 
     p.LastName, 
     COUNT(*) AS DAYS_ABOVE_100 
FROM (SELECT PersonID, Created, COUNT(*) 
     FROM Recordings 
     GROUP BY ID,Created 
     HAVING COUNT(*) > 100 
     )r 
JOIN Person p 
    ON r.PersonID = p.ID 
WHERE Created BETWEEN '2013-08-01 00:00:00.000' AND '2013-08-21 00:00:00.000' 
GROUP BY p.FirstName, 
      p.LastName 
ORDER BY DAYS_ABOVE_100 DESC 
Смежные вопросы