2013-08-29 59 views
0

SQL Server 2008 我有兩個OrderIds和ItemIds表。我需要一個結果表,其中來自forst表的每個OrderId都與第二個表中的OrderId鏈接,其中相同ItemIds的數量最大。現有的SQL Server 2008腳本改進

我做了一個使用兩個循環的腳本,但如果這些表中OrderIds的數量很大(〜1000),則意味着循環必須運行1000x1000次,這可能太長。這可以通過更好的方式實現嗎?

見我下面我已經寫好的劇本:

drop table #Match, #OrderRec, #OrderSent 

create table #Match(
    OrderIdRec int NULL, 
    OrderIdSent int NULL) 

create table #OrderRec(
    OrderIdRec  int  NOT NULL, 
    ItemId   int   NULL) 

create table #OrderSent(
    OrderIdSent  int  NOT NULL, 
    ItemId   int   NULL) 

insert #OrderRec values (1, 1) 
insert #OrderRec values (1, 5) 
insert #OrderRec values (1, 7) 
insert #OrderRec values (1, 4) 
insert #OrderRec values (1, 15) 
insert #OrderRec values (1, 10) 

insert #OrderRec values (2, 21) 
insert #OrderRec values (2, 15) 
insert #OrderRec values (2, 21) 
insert #OrderRec values (2, 26) 

insert #OrderRec values (5, 4) 
insert #OrderRec values (5, 3) 
insert #OrderRec values (5, 12) 
insert #OrderRec values (5, 1) 

insert #OrderSent values (121, 1) 
insert #OrderSent values (121, 2) 
insert #OrderSent values (121, 5) 
insert #OrderSent values (121, 10) 
insert #OrderSent values (121, 9) 

insert #OrderSent values (122, 6) 
insert #OrderSent values (122, 7) 
insert #OrderSent values (122, 9) 
insert #OrderSent values (122, 11) 

insert #OrderSent values (142, 1) 
insert #OrderSent values (142, 12) 
insert #OrderSent values (142, 4) 
insert #OrderSent values (142, 11) 

set nocount on 

declare @OrderIdRec int, 
     @OrderIdSent int, 
     @cnt numeric(10), 
     @cnt_max numeric(10), 
     @OrderIdSentMax int 

select @OrderIdRec = MIN(OrderIdRec) 
from #OrderRec 

while ISNULL(@OrderIdRec,0) > 0 
begin 

    select @OrderIdSent = MIN(OrderIdSent) 
    from #OrderSent 

    set @cnt_max = 0 
    set @OrderIdSentMax = NULL 

    while ISNULL(@OrderIdSent,0) > 0 
    begin 

     set @cnt = 0 

     select @cnt = COUNT(*) 
     from #OrderRec r 
      inner join #OrderSent t 
     on t.ItemId = r.ItemId 
     where r.OrderIdRec = @OrderIdRec 
     and t.OrderIdSent = @OrderIdSent 

     if isnull(@cnt, 0) > @cnt_max 
     begin 
      set @cnt_max = @cnt 
      set @OrderIdSentMax = @OrderIdSent  
     end 

     select @OrderIdSent = MIN(OrderIdSent) 
     from #OrderSent 
     where OrderIdSent > @OrderIdSent 
    end 

    insert #Match(
     OrderIdRec, 
     OrderIdSent) 
    values (@OrderIdRec, @OrderIdSentMax) 

    select @OrderIdRec = MIN(OrderIdRec) 
    from #OrderRec 
    where OrderIdRec > @OrderIdRec 
end 

select * 
from #Match 
order by OrderIdRec 

實際的腳本啓動與SET NOCOUNT上,什麼是之前只是創建一組數據一起玩的。

結果是:

OrderIdRec OrderIdSent 
1   121 
2   NULL 
5   142 

回答

0
;WITH s AS 
(
    SELECT OrderIdRec, OrderIdSent, 
    rn = ROW_NUMBER() OVER (PARTITION BY OrderIdRec ORDER BY c DESC) 
    FROM 
    (
    SELECT r.OrderIdRec, s.OrderIdSent, 
     c = COUNT(*) OVER (PARTITION BY r.OrderIdRec, s.OrderIdSent) 
    FROM #OrderRec AS r 
    INNER JOIN #OrderSent AS s 
    ON r.ItemId = s.ItemId 
) AS s2 
), 
d AS (SELECT OrderIdRec FROM #OrderRec GROUP BY OrderIdRec) 
SELECT d.OrderIdRec, s.OrderIdSent 
FROM d LEFT OUTER JOIN s 
ON d.OrderIdRec = s.OrderIdRec AND s.rn = 1 
ORDER BY d.OrderIdRec; 
+0

這很完美。謝謝。 –

0

下面的查詢獲取所有計數對兩個表之間:

select orec.OrderId, osent.OrderId, count(*) as cnt 
from OrderRec orec join 
    OrderSent osent 
    on orec.itemId = osent.itemId 
group by orec.OrderId, osent.OrderId; 

下獲取每個orec.OrderId最高CNT值:

select oo.* 
from (select orec.OrderId, osent.OrderId, count(*) as cnt, 
      row_number() over (partition by orec.OrderId, osent.OrderId order by count(*) desc 
           ) as seqnum 
     from OrderRec orec join 
      OrderSent osent 
      on orec.itemId = osent.itemId 
     group by orec.OrderId, osent.OrderId 
    ) oo 
where seqnum = 1; 
+0

Thanks Go rdon,但是你的腳本會返回與我的結果集不同的結果集。 'OrderIdRec OrderIdSent cnt seqnum 1 121 3 1 1 122 1 1 1 142 2 1 5 121 1 1 5 142 3 1' –

相關問題