SQL Server 2012 удаляет дубликаты с помощью ROW_NUMBER () OVER PARTITION - PullRequest
0 голосов
/ 09 ноября 2018

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

SQL ниже почти делает то, что я хочу, но дает мне только половину ожидаемых строк

SELECT
    Trade.tradedate AS TradeDate,
    Trade.status,
    contract.contract AS ContractID,
    'obsolete' AS ZainetRef,
    fee.feemode,
    position.counterparty,
    position.positiontype,
    Trade.cstcontractstart AS ContractStartDate, 
    Trade.cstcontractend AS ContractEndDate,
    contract.contracttype,
    CONVERT(INT, Trade.trade) AS TradeID,
    feetimeperiod.feetimeperiod,
    feetimeperiod.dbcolumn,
    feetimeperiod.dbvalue,
    (CONVERT(TIME, feetimeperiod.begtime)) AS TheTime,
    feetimeperiod.begtime AS FeeTimePeriodBeginTime,
    feetimeperiod.endtime AS FeeTimePeriodEndTime,
    loadshapeprofile.begtime AS StartDateTime,
    loadshapeprofile.endtime AS EndDateTime,
    loadshapeprofile.offset,
    loadshape.timeunit,
    CASE 
       WHEN CAST((loadshapeprofile.endtime - loadshapeprofile.begtime) AS INT) = 1 
          THEN 'D' 
       WHEN CAST((loadshapeprofile.endtime - loadshapeprofile.begtime) AS INT) > 1  
            AND CAST((loadshapeprofile.endtime - loadshapeprofile.begtime) AS INT) <= 31 
          THEN 'M' 
       WHEN CAST((loadshapeprofile.endtime - loadshapeprofile.begtime) AS INT) > 31 
            AND CAST((loadshapeprofile.endtime - loadshapeprofile.begtime) AS INT) <= 93 
          THEN 'Q'
       WHEN CAST((loadshapeprofile.endtime - loadshapeprofile.begtime) AS INT) > 93 
            AND CAST((loadshapeprofile.endtime - loadshapeprofile.begtime) AS INT) <= 183 
          THEN 'S'
       ELSE 'Y' 
    END AS BlockDescription,
    position.block,
    CAST((loadshapeprofile.endtime - loadshapeprofile.begtime) AS FLOAT) * 24.0  AS HoursInPeriod,
    CAST((loadshapeprofile.endtime - loadshapeprofile.begtime) AS INT) AS Days,
    position.unit,
    ISNULL(fee.pricediff,0) AS GBPMWh,
    CASE
       WHEN loadshape.timeunit = 'HALFHOUR' 
          THEN ((loadshapeprofile.he1 + loadshapeprofile.he2 + loadshapeprofile.he3 + loadshapeprofile.he4 + loadshapeprofile.he5 + loadshapeprofile.he6 + loadshapeprofile.he7 + loadshapeprofile.he8 + loadshapeprofile.he9 + loadshapeprofile.he10 + loadshapeprofile.he11 + loadshapeprofile.he12 + loadshapeprofile.he13 + loadshapeprofile.he14 + loadshapeprofile.he15 + loadshapeprofile.he16 + loadshapeprofile.he17 + loadshapeprofile.he18 + loadshapeprofile.he19 + loadshapeprofile.he20 + loadshapeprofile.he21 + loadshapeprofile.he22 + loadshapeprofile.he23 + loadshapeprofile.he24 + loadshapeprofile.he25) * 0.5)/24
    ELSE  
        ((loadshapeprofile.he1 + loadshapeprofile.he2 + loadshapeprofile.he3  + loadshapeprofile.he4 + loadshapeprofile.he5 + loadshapeprofile.he6 + loadshapeprofile.he7 + loadshapeprofile.he8 + loadshapeprofile.he9 + loadshapeprofile.he10 + loadshapeprofile.he11 + loadshapeprofile.he12 + loadshapeprofile.he13 + loadshapeprofile.he14 + loadshapeprofile.he15 + loadshapeprofile.he16 + loadshapeprofile.he17 + loadshapeprofile.he18 + loadshapeprofile.he19 + loadshapeprofile.he20 + loadshapeprofile.he21  + loadshapeprofile.he22 + loadshapeprofile.he23 + loadshapeprofile.he24 + loadshapeprofile.he25) )/24
    END AS MW,
    CASE
       WHEN loadshape.timeunit = 'HALFHOUR' 
          THEN 
    ((loadshapeprofile.he1 
    + loadshapeprofile.he2 
    + loadshapeprofile.he3 
    + loadshapeprofile.he4 
    + loadshapeprofile.he5
    + loadshapeprofile.he6
    + loadshapeprofile.he7
    + loadshapeprofile.he8
    + loadshapeprofile.he9
    + loadshapeprofile.he10
    + loadshapeprofile.he11
    + loadshapeprofile.he12
    + loadshapeprofile.he13
    + loadshapeprofile.he14
    + loadshapeprofile.he15
    + loadshapeprofile.he16 
    + loadshapeprofile.he17
    + loadshapeprofile.he18
    + loadshapeprofile.he19
    + loadshapeprofile.he20
    + loadshapeprofile.he21 
    + loadshapeprofile.he22
    + loadshapeprofile.he23
    + loadshapeprofile.he24
    + loadshapeprofile.he25) * 0.5) 
    ELSE  
    ((loadshapeprofile.he1 
    + loadshapeprofile.he2 
    + loadshapeprofile.he3 
    + loadshapeprofile.he4 
    + loadshapeprofile.he5
    + loadshapeprofile.he6
    + loadshapeprofile.he7
    + loadshapeprofile.he8
    + loadshapeprofile.he9
    + loadshapeprofile.he10
    + loadshapeprofile.he11
    + loadshapeprofile.he12
    + loadshapeprofile.he13
    + loadshapeprofile.he14
    + loadshapeprofile.he15
    + loadshapeprofile.he16 
    + loadshapeprofile.he17
    + loadshapeprofile.he18
    + loadshapeprofile.he19
    + loadshapeprofile.he20
    + loadshapeprofile.he21 
    + loadshapeprofile.he22
    + loadshapeprofile.he23
    + loadshapeprofile.he24
    + loadshapeprofile.he25))
END AS MWh,
CASE
    WHEN loadshape.timeunit = 'HALFHOUR' THEN 
    ((loadshapeprofile.he1 
    + loadshapeprofile.he2 
    + loadshapeprofile.he3 
    + loadshapeprofile.he4 
    + loadshapeprofile.he5
    + loadshapeprofile.he6
    + loadshapeprofile.he7
    + loadshapeprofile.he8
    + loadshapeprofile.he9
    + loadshapeprofile.he10
    + loadshapeprofile.he11
    + loadshapeprofile.he12
    + loadshapeprofile.he13
    + loadshapeprofile.he14
    + loadshapeprofile.he15
    + loadshapeprofile.he16 
    + loadshapeprofile.he17
    + loadshapeprofile.he18
    + loadshapeprofile.he19
    + loadshapeprofile.he20
    + loadshapeprofile.he21 
    + loadshapeprofile.he22
    + loadshapeprofile.he23
    + loadshapeprofile.he24
    + loadshapeprofile.he25) * 0.5)  * ISNULL(fee.pricediff,0)
    ELSE  
    ((loadshapeprofile.he1 
    + loadshapeprofile.he2 
    + loadshapeprofile.he3 
    + loadshapeprofile.he4 
    + loadshapeprofile.he5
    + loadshapeprofile.he6
    + loadshapeprofile.he7
    + loadshapeprofile.he8
    + loadshapeprofile.he9
    + loadshapeprofile.he10
    + loadshapeprofile.he11
    + loadshapeprofile.he12
    + loadshapeprofile.he13
    + loadshapeprofile.he14
    + loadshapeprofile.he15
    + loadshapeprofile.he16 
    + loadshapeprofile.he17
    + loadshapeprofile.he18
    + loadshapeprofile.he19
    + loadshapeprofile.he20
    + loadshapeprofile.he21 
    + loadshapeprofile.he22
    + loadshapeprofile.he23
    + loadshapeprofile.he24
    + loadshapeprofile.he25) * ISNULL(fee.pricediff,0))
END AS BlockCost,
    loadshapeprofile.he1,   
    loadshapeprofile.he2,   
    loadshapeprofile.he3,   
    loadshapeprofile.he4,
    loadshapeprofile.he5,   
    loadshapeprofile.he6,   
    loadshapeprofile.he7,   
    loadshapeprofile.he8,   
    loadshapeprofile.he9,   
    loadshapeprofile.he10,  
    loadshapeprofile.he11,  
    loadshapeprofile.he12,  
    loadshapeprofile.he13,  
    loadshapeprofile.he14,  
    loadshapeprofile.he15,  
    loadshapeprofile.he16,  
    loadshapeprofile.he17,  
    loadshapeprofile.he18,  
    loadshapeprofile.he19,  
    loadshapeprofile.he20,  
    loadshapeprofile.he21,  
    loadshapeprofile.he22,  
    loadshapeprofile.he23,  
    loadshapeprofile.he24,  
    loadshapeprofile.he25   
from Trade
inner join position on trade.trade = position.trade
inner join contract on position.contract = contract.contract
inner join loadshape on position.loadshape = loadshape.loadshape
inner join loadshapeprofile on loadshape.loadshape = loadshapeprofile.loadshape 
inner join fee on position.position = fee.dbvalue 
inner join feetimeperiod on fee.feetimeperiod = feetimeperiod.feetimeperiod and feetimeperiod.dbvalue = position.position
where contract.contract = '1111111'
and position.loadshape is not null
and fee.dbcolumn = 'POSITION' 
and fee.feemethod = 'COMMODITY PRICE'
and (CAST(DATEPART(MINUTE, feetimeperiod.begtime ) as decimal) = loadshapeprofile.offset)
and Trade.status = 'ACTIVE'
and trade.trade = 261333
and Trade.tradestatus IN ('FO Approval','TC Approval')
and feetimeperiod.feetimeperiod IN (select feetimeperiod from (select feetimeperiod, begtime, loadshapeprofile.offset, ROW_NUMBER() over (partition by  CONVERT(date,feetimeperiod.begtime), CONVERT(date,feetimeperiod.endtime),loadshapeprofile.offset order by CONVERT(date,feetimeperiod.begtime)) RowNumber from feetimeperiod) ftp where (ftp.RowNumber = 1 AND (CONVERT(date,ftp.begtime) =  CONVERT(date,loadshapeprofile.begtime) )) )
order by feetimeperiod.begtime

Я стремлюсь получить 2 строки для каждого FeeTimePeriodBeginTime (date), одну строку со смещением 0 и другую со смещением 30, которые фактически дают мне один день, но я действительно чешу голову (я даже собираюсь об этом правильный путь?)

любая помощь будет принята с благодарностью

Ответы [ 2 ]

0 голосов
/ 12 ноября 2018

В конце концов мне удалось выяснить это самостоятельно, я использовал общее табличное выражение

;WITH FeePeriod_CTE 
AS
(
	select feetimeperiod.feetimeperiod, 
		feetimeperiod.begtime, 
		feetimeperiod.endtime, 
		loadshapeprofile.offset, 
		ROW_NUMBER() over (partition by CONVERT(date,feetimeperiod.begtime),CONVERT(date,feetimeperiod.endtime),loadshapeprofile.offset order by CONVERT(date,feetimeperiod.begtime)) RowNumber 
		from trade
		inner join position on trade.trade = position.trade
		inner join contract on position.contract = contract.contract
		inner join loadshape on position.loadshape = loadshape.loadshape
		inner join loadshapeprofile on loadshape.loadshape = loadshapeprofile.loadshape 
		inner join fee on position.position = fee.dbvalue 
		inner join feetimeperiod on fee.feetimeperiod = feetimeperiod.feetimeperiod and feetimeperiod.dbvalue = position.position
		where contract.contract = '110156'
		and position.loadshape is not null
		and fee.dbcolumn = 'POSITION' 
		and fee.feemethod = 'COMMODITY PRICE'
		and (CAST(DATEPART(MINUTE, feetimeperiod.begtime ) as decimal) = loadshapeprofile.offset)
		and Trade.status = 'ACTIVE'
		and trade.trade = 261333
		and Trade.tradestatus IN ('FO Approval','TC Approval')
		AND (CONVERT(date,feetimeperiod.begtime) =  CONVERT(date,loadshapeprofile.begtime) )
)

и затем добавил эту строку в предложении WHERE

and feetimeperiod.feetimeperiod IN (select feetimeperiod from FeePeriod_CTE where RowNumber = 1)

Теперь отлично работает

0 голосов
/ 09 ноября 2018

Ваша проблема не в том, что row_number, а в том, что вы использовали row_number с условием "IN". SQL Server удаляет дубликаты с условием «IN». Если вы хотите увидеть дублированные строки, вам нужно «ПРИСОЕДИНИТЬСЯ» к нему.

...