[英]Query to distribute value from one table to another by 1
table A
將有table B
b 中的一種食物
Table A
Name | Value | Food
-----------------------------
Ahmed | 1 |
Ali | 83 |
Peter | 19 |
Sam | 8 |
Sara | 9 |
Loyel | 101 |
Table B
FoodName | Remaining
-------------------
Apple | 3
Mango | 2
Table A
Name | Value | Food
-----------------------------
Ahmed | 1 | Apple
Ali | 83 | Apple
Peter | 19 | Apple
Sam | 8 | Mango
Sara | 9 | Mango
Loyel | 101 | Null
什么是設置的基本查詢,我想在哪里避免循環,或者我已經實現的遞歸 function?
這是使用 window 函數的黑客方法,特別是ROW_NUMBER
:
WITH cteB AS (
SELECT FoodName, Remaining,
COALESCE(SUM(Remaining) OVER (ORDER BY FoodName ROWS BETWEEN UNBOUNDED PRECEDING AND PRECEDING ROW), 0) AS RemainingStart,
SUM(Remaining) OVER (ORDER BY FoodName) RemainingEnd
FROM TableB
),
cteA AS (
SELECT Name, Value, ROW_NUMBER() OVER (ORDER BY Name) rn
FROM TableA
)
SELECT
a.Name,
a.Value,
b.FoodName AS Food
FROM cteA a
LEFT JOIN cteB b
ON a.rn > b.RemainingStart AND a.rn <= b.RemainingEnd;
我使用的邏輯背后的想法是使用 window 函數為 B 表中的每個項目生成一個偽食品訂單,編號從 0 到食品的總數。 然后,還為 A 表中的每個人分配一個行號,然后使用此偽序列將人員與食物項進行匹配。
請注意,在我們可能想要多次迭代並將多個食物分配給每個人的情況下,我的回答不足。
你不需要循環。
select a.Name, a.Value, b.FoodName
from
(select *, row_number() over(order by Name) rn
from tabeA) a
left join
(select *, sum(Remaining) over(order by FoodName) running_total
from tableB) b on a.rn between b.running_total - b.Remaining + 1 and b.running_total;
如果您需要對TableA
進行其他排序,請根據需要更改row_number() over(order by Name)
。
這是一種使用遞歸 CTE 為每個剩余水果生成包含行的表的方法。 然后它必須通過 row_number 連接到 tableA,tableA 的 row_number 有效地隨機生成:
with cte as (
select FoodName, Remaining from tableB
union all
select FoodName, Remaining - 1 from cte
where Remaining - 1 > 0)
select a.Name, a.[value], c.FoodName
from (select *,
row_number() over (order by (select 1)) as rn
from tableA) a
left join (select *,
row_number() over (order by FoodName, Remaining) as rn
from cte) c on c.rn = a.rn
Output:
Name value FoodName
Ahmed 1 Apple
Ali 83 Apple
Peter 19 Apple
Sam 8 Mango
Sara 9 Mango
Loyel 101
更新
由於有一個id
標識列,我們可以按它來排序。 在查詢中將(order by (select 1))
更改為(order by id)
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.