如何从一个表中选择100条记录,为另一个表中的每个唯一记录选择

时间:2020-09-09 16:34:03

标签: sql sql-server join window-functions

我有一张地址表,另一张优惠券表。我想为每个地址选择10张优惠券。我将如何去做?我知道这是非常基本的,但是我已经离开SQL一段时间了,试图尽我所能重新熟悉它。

表1

Name      Address
-------------------
Store 1   Address 1
Store 2   Address 2

表2

Coupons
--------
coupon1
coupon2
...
coupon19
coupon20

4 个答案:

答案 0 :(得分:1)

您可以使用窗口功能:

select t1.*, t2.coupons
from (
    select t1.*, row_number() over(order by id) rn
    from table1 t1
) t1
inner join (
    select t2.*, row_number() over(order by id) rn
    from table2 t2
) t2 on (t2.rn - 1) / 10 = t1.rn

这个想法是用row_number()枚举每个表的行,然后将结果与行号的条件结合起来。上面的查询为您提供了每个地址10张优惠券。

要获得稳定的结果,您需要在每个表中唯一地标识每一行的一列(或一组列):我假设两个表中的id

答案 1 :(得分:0)

您要每个商店10张优惠券吗?每个商店100张优惠券?您的问题回复与帖子不同。还是您想在所有商店中平均分配所有可用的优惠券?此查询中的一些查询正在构建数据以演示输出,但要重点关注的是使用NTILE(10)将优惠券分成十组,然后可以对其应用ROW_NUMBER,从而为您提供每个id值可使用10张优惠券...

WITH random_data AS
(
    SELECT  ROW_NUMBER() OVER (ORDER BY id) AS nums
    FROM    sysobjects
),  store_info AS
(
    SELECT  ROW_NUMBER() OVER (ORDER BY nums) AS join_id,
            'Store' + CONVERT(VARCHAR(10),nums) AS StoreName,
            'Address' + CONVERT(VARCHAR(10),nums) AS StoreAddress
    FROM    random_data
),  more_random_data    AS
(
    SELECT  ROW_NUMBER() OVER (ORDER BY t2.nums) AS nums
    FROM    random_data t1
    CROSS   JOIN random_data t2
),  coupons AS
(
    SELECT  NTILE(10) OVER (ORDER BY nums) AS group_id,
            'Coupon' + CONVERT(VARCHAR(10),nums) AS Coupon,
            nums
    FROM    more_random_data
),  coupons_with_join_id AS
(
    SELECT  ROW_NUMBER() OVER (PARTITION BY group_id ORDER BY nums) AS join_id,
            Coupon
    FROM    coupons
)
SELECT  StoreName, StoreAddress, Coupon
FROM    store_info AS si
JOIN    coupons_with_join_id AS cwji
    ON  si.join_id = cwji.join_id
ORDER   BY si.join_id, Coupon

答案 2 :(得分:0)

这里的固有问题是2个表之间没有关系。因此,您的选择要么是像其他答案所示那样强制伪关系,要么是在两个表之间创建关系,例如在优惠券表中添加store_name列。

答案 3 :(得分:0)

这将 all 个优惠券(几乎)平均分配到 all 个地址:

with addr as
 ( -- prepare addresses by adding a sequence
   select Name, Address, 
      -- 1-n
      row_number() over (order by name) as rn
   from table1
 )
 ,coup as
 ( -- prepare coupons by adding same "sequence"
   select coupons,
      -- 1-n, same number of coupons (+/-1) for each address
      ntile((select count(*) from table1))
      over (order by coupons) as num
   from table2
 )
select * 
from addr 
join coup
on addr.rn = coup.num
相关问题