【问题标题】:How do I select 100 records from one table for each unique record from another如何从一个表中为另一个表中的每个唯一记录选择 100 条记录
【发布时间】:2020-12-28 03:17:37
【问题描述】:

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

表 1

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

表 2

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

【问题讨论】:

  • 哪10张优惠券?
  • 一共有128家店铺,128000张优惠券。每家商店每人需要 100 张优惠券。所以说商店 1 为 1-100,商店 2 为 101-200,依此类推。
  • 使用 SQL Server,您可以使用行号。您加入两个表,然后运行行号并选择行号小于 10 的行。这里是 example

标签: sql sql-server join window-functions


【解决方案1】:

这会将所有张优惠券(几乎)均匀地分布在所有个地址中:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      你可以使用窗口函数:

      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

      【讨论】:

        【解决方案4】:

        您想要每家商店有 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
        

        【讨论】:

          猜你喜欢
          • 2021-01-26
          • 1970-01-01
          • 2022-01-21
          • 2021-12-10
          • 2021-08-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-10-08
          相关资源
          最近更新 更多