![](/img/trans.png)
[英]How do I show all records from one table for each semi-related record in another?
[英]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.