0

SQL Server 2008 我有两个带有 OrderIds 和 ItemIds 的表。我需要一个结果表,其中每个 OrderId 来自 forst 表与第二个表中的 OrderId 链接,其中相同 ItemId 的数量最大。

我做了一个使用两个循环执行此操作的脚本,但如果这些表中的 OrderId 数量很大(~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 on 开始,之前只是创建一组数据来玩。

结果是:

OrderIdRec  OrderIdSent
1            121
2            NULL
5            142
4

2 回答 2

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;

以下获取每个的最高 cnt 值orec.OrderId

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;
于 2013-08-29T02:03:20.293 回答
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;
于 2013-08-29T03:32:04.330 回答