sql определение строки по количеству раз / как она выглядит как другие строки - PullRequest
3 голосов
/ 14 сентября 2010

Я хочу переклассифицировать некоторую относительно простую информацию наиболее эффективным из возможных способов: используя ограниченный выбор выборочных данных:

CREATE TABLE #data
(id varchar(30)
,payent_type varchar(30)
,payment_date DATETIME)

INSERT INTO #data values ('001','single gift',DATEADD(MM,-12,GETDATE()))
INSERT INTO #data values ('001','regular gift',DATEADD(MM,-39,GETDATE()))
INSERT INTO #data values ('002','regular gift',DATEADD(MM,-06,GETDATE()))
INSERT INTO #data values ('003','single gift',DATEADD(MM,-96,GETDATE()))
INSERT INTO #data values ('003','regular gift',DATEADD(MM,-96,GETDATE()))
INSERT INTO #data values ('003','single gift',DATEADD(MM,-1,GETDATE()))
INSERT INTO #data values ('004','single gift',DATEADD(MM,-54,GETDATE()))
INSERT INTO #data values ('005','regular gift',DATEADD(MM,-2,GETDATE()))
INSERT INTO #data values ('005','regular gift',DATEADD(MM,-8,GETDATE()))
INSERT INTO #data values ('006','single gift',DATEADD(MM,-12,GETDATE()))
INSERT INTO #data values ('007','regular gift',DATEADD(MM,-2,GETDATE()))
INSERT INTO #data values ('007','regular gift',DATEADD(MM,-6,GETDATE()))
INSERT INTO #data values ('008','single gift',DATEADD(MM,-1,GETDATE()))
INSERT INTO #data values ('009','single gift',DATEADD(MM,-80,GETDATE()))
INSERT INTO #data values ('010','single gift',DATEADD(MM,-54,GETDATE()))

и превращая его в следующее:

ID   |   2005  |  2006  |  2007         |  2008  |  2009       |  2010
001  |   NULL  |  NULL  |  regular gift |  NULL  |  Both gifts |  NULL

Где, в принципе, если у ID есть как один, так и обычный подарок на год, тогда назовите его «оба подарка», если есть только один подарок, то «единственный подарок», а если есть только обычный подарок, то «обычный подарок».

Эти данные затем будут использоваться как часть другого более крупного запроса.

Я считаю, что достаточно легко понять, дал ли ID когда-либо один или обычный (или оба) подарок., но я изо всех сил пытаюсь решить это из года в год, не создавая ряд временных таблиц, которые сильно замедляют работу

Заранее спасибо :)

РЕДАКТИРОВАТЬ Это очень упрощенная версия фактических данных, которые у меня есть - реальные данные имеют до 200 строк на один идентификатор и могут содержать несколько подарков в год для каждого типа.

Ответы [ 3 ]

2 голосов
/ 14 сентября 2010

Это соответствует тому, что вам нужно?

;with IDYearSummary as
(
    select
        id,
        MAX(CASE payment_type WHEN 'single gift' THEN 1 ELSE 0 END) as single,
        MAX(CASE payment_type WHEN 'regular gift' THEN 1 ELSE 0 END) as regular,
        DATEPART(year,payment_date) as year
    from
        #data
    group by
        id,DATEPART(year,payment_date)
), MixGifts as
(
    select
        id,
        CASE
            WHEN single=1 and regular=1 THEN 'both'
            WHEN single=1 THEN 'single'
            WHEN regular=1 THEN 'regular'
        END as gifts,
        year
    from
        IDYearSummary
)
select
    id,
    [2002],
    [2003],
    [2004],
    [2005],
    [2006],
    [2007],
    [2008],
    [2009],
    [2010]
from
    MixGifts
        pivot (MAX(gifts) FOR year in ([2002],[2003],[2004],[2005],[2006],[2007],[2008],[2009],[2010])) as pvt


drop table #data
1 голос
/ 14 сентября 2010
WITH Data AS
    ( SELECT id, YEAR(payment_date) AS payment_year,
        CASE
            WHEN MAX(payent_type)<> MIN(payent_type)
            THEN 'Both gifts'
            ELSE MAX(payent_type)
        END AS payent_type
    FROM #data
    GROUP BY YEAR(payment_date),
        id
    )
select id,[2002],[2003],[2004],[2005],[2006],[2007],[2008],[2009],[2010]
from data
Pivot  (max(payent_type) for 
      payment_year in ([2002],[2003],[2004],[2005],[2006],[2007],[2008],[2009],[2010])) pvt
1 голос
/ 14 сентября 2010

Этот запрос работает с использованием предоставленных вами тестовых данных.

Select * 
From
(
Select  ID, 
        'both gift' as 'PaymentType',
        Datepart(Year, payment_date) as 'Years'
From #data
Group by Id, Datepart(Year, payment_date)
Having Count(Distinct(Payment_Type)) > 1

    Union All

Select  ID, 
        Max(Payment_Type),
        Datepart(Year, payment_date)
From #data
Group by Id, Datepart(Year, payment_date)
Having Count(Distinct(Payment_Type)) = 1

    Union All

Select  ID, 
        Null,
        Datepart(Year, payment_date)
From #data
Group by Id, Datepart(Year, payment_date)
Having Count(Distinct(Payment_Type)) = 0
)q

Pivot  (max(PaymentType) for Years in ([2002],[2003],[2004],[2005],[2006],[2007],[2008],[2009],[2010])
)p
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...