I have one table of addresses, another table of coupons. I want to select 10 coupons per address. 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...
Table 1
Name Address
-------------------
Store 1 Address 1
Store 2 Address 2
Table 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. The above query gives you 10 coupons per address.
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.
Do you want 10 coupons per store? 100 coupons per store? 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...
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.
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.