[英]How do I select 100 records from one table for each unique record from another
I have one table of addresses, another table of coupons.我有一张地址表,另一张优惠券表。 I want to select 10 coupons per address.我想为每个地址选择 10 张优惠券。 How would I go about doing that?我该怎么做? I know this is very basic, but I've been out of SQL for some time now and trying to get reacquainted with it the best I can...我知道这是非常基本的,但我已经有一段时间没有使用 SQL 了,并试图尽我所能重新熟悉它......
Table 1表格1
Name Address
-------------------
Store 1 Address 1
Store 2 Address 2
Table 2表 2
Coupons
--------
coupon1
coupon2
...
coupon19
coupon20
You can use window functions:您可以使用窗口函数:
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
The idea is to enumerate rows of each table with row_number()
, then join the results with a condition on the row numbers.这个想法是用row_number()
枚举每个表的行,然后用行号的条件连接结果。 The above query gives you 10 coupons per address.上述查询为每个地址提供 10 张优惠券。
To get a stable result, you need a column (or a set of columns) in each table that uniquely identifies each row: I assumed id
in both tables.为了获得稳定的结果,您需要在每个表中有一列(或一组列)来唯一标识每一行:我假设两个表中的id
。
Do you want 10 coupons per store?您想要每家商店 10 张优惠券吗? 100 coupons per store?每家店100张优惠券? Your question response is different than the post.您的问题回复与帖子不同。 Or maybe you'd like to evenly distribute all available coupons across all the stores?或者您想在所有商店中均匀分发所有可用的优惠券? Some of this query is building data to be able to demonstrate the output, but the main thing to focus on is the using of NTILE(10) to break up the Coupons into ten groups that can then have a ROW_NUMBER applied to it that gives you ten coupons per id value that can be joined upon...此查询中的一些正在构建能够演示输出的数据,但主要关注的是使用 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
The inherent issue here is that the 2 tables have no relation to each other.这里的固有问题是这两个表彼此没有关系。 So your options are either to force a pseudo relation, like the other answers show, or create a relation between the two tables, like adding a store_name column to the coupon table.因此,您的选择要么是强制伪关系,如其他答案所示,要么在两个表之间创建关系,如向优惠券表添加 store_name 列。
This distributes all coupons (almost) evenly across all adresses:这将所有优惠券(几乎)平均分配到所有地址:
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.