Определите полные или полугодовые наборы данных в SQL - PullRequest
1 голос
/ 13 октября 2008

У меня есть таблица с двумя полями интереса для этого конкретного упражнения: ID CHAR (3) и DATETIME. Идентификатор идентифицирует отправителя данных - несколько тысяч строк. DATETIME также не обязательно уникален. (Первичные ключи - это другие поля таблицы.)

Данные для этой таблицы представляются каждые шесть месяцев. В декабре мы получаем данные за июль-декабрь от каждого отправителя, а в июне мы получаем данные за июль-июнь. Моя задача - написать скрипт, который идентифицирует людей, которые представили только половину своих данных или только в январе-июне представили данные в июне.

... У кого-нибудь есть решение?

Ответы [ 3 ]

1 голос
/ 15 октября 2008

Ради интереса, это то, что я использовал. Это было основано на ответе Стивена, но с некоторыми изменениями. У меня пока нет репутации, чтобы поддержать его. :.)

Это часть более крупного скрипта, который запускается каждые шесть месяцев, но мы проверяем это только каждые двенадцать месяцев - отсюда и «If FullYear = 1». Я уверен, что есть более стильный способ определения дат границы, но, похоже, это сработает.

IF @FullYear = 1 
    BEGIN
        DECLARE @FirstDate AS DATETIME
        DECLARE @LastDayFirstYear AS DATETIME
        DECLARE @SecondYear AS INT
        DECLARE @NewYearsDay AS DATETIME
        DECLARE @LastDate AS DATETIME

        SELECT @FirstDate = MIN(dscdate), @LastDate = MAX(dscdate)
        FROM    TheTable

        SELECT  @SecondYear = DATEPART(yyyy, @FirstDate) + 1
        SELECT  @NewYearsDay = CAST(CAST(@SecondYear AS VARCHAR) 
            + '-01-01' AS DATETIME)

        INSERT  INTO @AuditResults
                SELECT DISTINCT
                    'Submitter missing Jan-Jun data', t.id
                FROM    TheTable t
                WHERE   
                    EXISTS ( 
                        SELECT 1
                        FROM   TheTable t1
                        WHERE  t.id = t1.id 
                            AND t1.date >= @FirstDate
                            AND t1.date < @NewYearsDay )
                    AND NOT EXISTS ( 
                        SELECT 1
                        FROM   TheTable t2
                        WHERE  t2.date >= @NewYearsDay
                        AND t2.date <= @LastDate
                        AND t2.id = t.id
                        GROUP BY t2.id )
                GROUP BY t.id
    END
1 голос
/ 13 октября 2008

из вашего описания, я бы не беспокоился об эффективности запроса, так как, очевидно, он должен выполняться только два раза в год!

Есть несколько способов сделать это, один из которых «лучший» зависит от данных, которые у вас есть. предлагаемый вами дата (на макс. / мин. значениях даты) должна работать, другой вариант - просто подсчитать записи для каждой из представленных в каждом диапазоне дат, например,

select * from (
    select T.submitterId,
        (select count(*) 
        from TABLE T1
        where T1.datefield between [july] and [december]
        and T1.submitterId = T.submitterId
        group by T1.submitterId) as JDCount,
        (select count(*)
        from TABLE T2
        where T2.datefield between [december] and [june]
        and T2.submitterId = T.submitterId
        group by T2.submitterId) as DJCount
    from TABLE T) X
where X.JDCount <= 0 OR X.DJCount <= 0

предостережение: непроверенный запрос с макушки головы; Ваш пробег может варьироваться

0 голосов
/ 17 февраля 2009

Позже я понял, что должен был проверить, чтобы убедиться, что есть данные для и с июля по декабрь и с января по июнь. Так вот что я завел в v2:

SELECT  @avgmonths = AVG(x.[count])
FROM    ( SELECT    CAST(COUNT(DISTINCT DATEPART(month,
                                                 DATEADD(month,
                                                         DATEDIFF(month, 0, dscdate),
                                                         0))) AS FLOAT) AS [count]
          FROM      HospDscDate
          GROUP BY  hosp
         ) x

IF @avgmonths > 7 
    SET @months = 12
ELSE 
    SET @months = 6


SELECT  'Submitter missing data for some months' AS [WarningType],
     t.id
FROM    TheTable t
WHERE   EXISTS ( SELECT 1
                 FROM   TheTable t1
                 WHERE  t.id = t1.id
                 HAVING COUNT(DISTINCT DATEPART(month,
                       DATEADD(month, DATEDIFF(month, 0, t1.Date), 0))) < @months )
GROUP BY t.id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...