Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 按1将值从一个表分配到另一个表的查询_Sql_Sql Server - Fatal编程技术网

Sql 按1将值从一个表分配到另一个表的查询

Sql 按1将值从一个表分配到另一个表的查询,sql,sql-server,Sql,Sql Server,表A将有表B中的一种食物 设置基查询是什么,我想避免循环,还是我实现的递归函数?下面是一种黑客方法,使用窗口函数,特别是行数: 我使用的逻辑背后的想法是,使用窗口函数为B表中的每一项生成一个伪食品订单,从0到食品项目总数。然后,还要为表中的每个人指定一个行号,然后使用这个伪序列将人与食物项匹配起来 请注意,我的答案不适用于我们可能需要多次迭代并为每个人分配多个食物项目的情况。您不需要循环 select a.Name, a.Value, b.FoodName from (select *, r

表A将有表B中的一种食物


设置基查询是什么,我想避免循环,还是我实现的递归函数?

下面是一种黑客方法,使用窗口函数,特别是行数:

我使用的逻辑背后的想法是,使用窗口函数为B表中的每一项生成一个伪食品订单,从0到食品项目总数。然后,还要为表中的每个人指定一个行号,然后使用这个伪序列将人与食物项匹配起来

请注意,我的答案不适用于我们可能需要多次迭代并为每个人分配多个食物项目的情况。

您不需要循环

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进行另一次排序,请根据需要按名称更改行号overorder。

这里有一个方法,使用递归CTE生成一个表,其中包含每个剩余水果的行。然后必须按行号将其连接到tableA,并有效地随机生成tableA的行号:

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
输出:

Name    value   FoodName
Ahmed   1       Apple
Ali     83      Apple
Peter   19      Apple
Sam     8       Mango
Sara    9       Mango
Loyel   101     
更新

因为有一个id-identity列,所以我们可以改为按该列排序。在查询中将订单按选择1更改为订单按id


您使用的是哪种数据库管理系统?SQL server 2017为什么Loyel没有水果?@gvee在他们得到Loyel 5片水果,6个名字之前,所有的都用完了。@QuaperClient很棒。我们都可以按顺序修改答案,以便给出一致的结果。按选择1排序的行数不保证任何顺序。在许多情况下,插入行的顺序是一样的,但总有一天会不一样。@Serg你是对的,所以我在评论中问了这个问题。@Serg你会注意到我在回答中写的tableA的行数实际上是随机的。@Serg OP本身并没有给出任何明确的顺序,所以Nick的假设是合理的。@Nick我刚刚了解到窗口框架语法取决于SQL Server中使用的语言环境。在欧洲机器上,它在1之前,而在美国机器上,它在1之前。这就是为什么我的第一次尝试没有成功。真奇怪!如果你有一个在两大洲的团队会发生什么?是的,这是一个非常好的问题。如果你不相信我:-@TimBiegeleisen我想知道,你为什么要在无界的前一行和前一行之间使用。因为它等于和partition@ErsinGülbahar问题是,我需要对所有以前的记录进行求和,除了帧中的当前记录。例如,对于mango,我希望它的范围从3到3+2的总和,也就是说,从3到5,以覆盖分配给mango的2个用户。仅仅取总数就会超过一个记录。
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
Name    value   FoodName
Ahmed   1       Apple
Ali     83      Apple
Peter   19      Apple
Sam     8       Mango
Sara    9       Mango
Loyel   101