繁体   English   中英

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

[英]How do I select 100 records from one table for each unique record from another

我有一张地址表,另一张优惠券表。 我想为每个地址选择 10 张优惠券。 我该怎么做? 我知道这是非常基本的,但我已经有一段时间没有使用 SQL 了,并试图尽我所能重新熟悉它......

表格1

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

表 2

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

您可以使用窗口函数:

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM