【问题标题】:Adding rows to a table respecting the key columns structure根据键列结构向表中添加行
【发布时间】:2021-04-27 07:55:17
【问题描述】:

我有一个非常大的表,它遵循以下结构(我在这里简化了过去):

Product Line Name Quantity Unit Cost
Pepe 10000 Lucia 4 UD 8
Pepe 20000 Santiago 7 UD 5.5
Pepe 30000 Mariangeles 10 KG 6
Antonio 10000 Naiara 4 KG 8
Antonio 20000 Toni 7 KG 3
Vanesa 10000 Lucia 4 UD 8
Vanesa 20000 Santiago 7 KG 8
Vanesa 30000 Toni 10 KG 3
Vanesa 40000 Gines 4 KG 8

我需要为每个产品添加一个新名称(Dany),所以表格如下所示:

姓名:丹妮;数量:15;单位:L;费用:2

结果是:

Product Line Name Quantity Unit Cost
Pepe 10000 Lucia 4 UD 8
Pepe 20000 Santiago 7 UD 5.5
Pepe 30000 Mariangeles 10 KG 6
Pepe 40000 Dany 15 L 2
Antonio 10000 Naiara 2 KG 8
Antonio 20000 Toni 7 KG 3
Antonio 30000 Dany 15 L 2
Vanesa 10000 Lucia 4 UD 8
Vanesa 20000 Santiago 7 KG 8
Vanesa 30000 Toni 10 KG 3
Vanesa 40000 Gines 4 KG 8
Vanesa 50000 Dany 15 L 2

事实上,“行”必须是现有的后续编号(例如,如果产品的姓氏是 30000(请参阅 Pepe),则 Dany 的行行必须是 40000,如果姓氏一个产品的数量是 20000,Dany 的行线必须是 30000(参见 Antonio)。

我可以使用 SQL(DBeaver 或 Microsoft Access)或 R 来完成,我正在考虑使用 R 循环或使用 count() 的 SQL 复杂查询,但非常感谢一些帮助。

非常感谢。

【问题讨论】:

  • 请注明您的数据库管理系统的版本。
  • 我使用 DBeaver 或 Microsoft Access 通过 SQL 进行这些类型的更改(两者都是最新版本)。该表的行数少于 1000。

标签: sql r


【解决方案1】:

您可以使用insert 将值插入到表中:

insert into t (Product, Line, Name, Quantity, Unit, Cost)
    select product, max(line) + 10000, 'Dany', 15, 'L', 2
    from t
    group by product;

如果不想修改表,只想看数据,可以运行查询:

select Product, Line, Name, Quantity, Unit, Cost
from t
union all
select product, max(line) + 10000, 'Dany', 15, 'L', 2
from t
group by product

【讨论】:

  • @r2evans 。 . .谢谢。
【解决方案2】:

我相信 SQL 可能是更好的地方,但如果您想知道如何在 R 中执行此操作,我假设您已经将相关数据下载到 dat

(在所有三个示例中,order/arrange 的使用仅用于演示,在生产中不需要。)

基础 R

newdat <- data.frame(Quantity=15L, Name="Dany", Unit="L", Cost=2)
newlines <- aggregate(dat$Line, list(Product=dat$Product), FUN=function(z) max(z) + 10000)
names(newlines)[2] <- "Line"
newlines
#   Product  Line
# 1 Antonio 30000
# 2    Pepe 40000
# 3  Vanesa 50000
out <- rbind(dat, merge(newlines, newdat, by = NULL))
out <- out[order(out$Product, out$Line),]
out
#    Product  Line        Name Quantity Unit Cost
# 4  Antonio 10000      Naiara        4   KG  8.0
# 5  Antonio 20000        Toni        7   KG  3.0
# 10 Antonio 30000        Dany       15    L  2.0
# 1     Pepe 10000       Lucia        4   UD  8.0
# 2     Pepe 20000    Santiago        7   UD  5.5
# 3     Pepe 30000 Mariangeles       10   KG  6.0
# 11    Pepe 40000        Dany       15    L  2.0
# 6   Vanesa 10000       Lucia        4   UD  8.0
# 7   Vanesa 20000    Santiago        7   KG  8.0
# 8   Vanesa 30000        Toni       10   KG  3.0
# 9   Vanesa 40000       Gines        4   KG  8.0
# 12  Vanesa 50000        Dany       15    L  2.0

tidyverse

library(dplyr)
# library(tidyr) # crossing

# newdat from above
dat %>%
  group_by(Product) %>%
  summarize(Line = max(Line) + 10000) %>%
  tidyr::crossing(., newdat) %>%
  bind_rows(dat) %>%
  arrange(Product, Line)
# # A tibble: 12 x 6
#    Product  Line Quantity Name        Unit   Cost
#    <chr>   <dbl>    <int> <chr>       <chr> <dbl>
#  1 Antonio 10000        4 Naiara      KG      8  
#  2 Antonio 20000        7 Toni        KG      3  
#  3 Antonio 30000       15 Dany        L       2  
#  4 Pepe    10000        4 Lucia       UD      8  
#  5 Pepe    20000        7 Santiago    UD      5.5
#  6 Pepe    30000       10 Mariangeles KG      6  
#  7 Pepe    40000       15 Dany        L       2  
#  8 Vanesa  10000        4 Lucia       UD      8  
#  9 Vanesa  20000        7 Santiago    KG      8  
# 10 Vanesa  30000       10 Toni        KG      3  
# 11 Vanesa  40000        4 Gines       KG      8  
# 12 Vanesa  50000       15 Dany        L       2  

数据表

library(data.table)
datDT <- as.data.table(dat)
newdatDT <- as.data.table(newdat)
newlinesDT <- datDT[, .(Line = max(Line) + 10000), by = .(Product)]

rbindlist(list(
  datDT,
  base::merge.data.frame(newlinesDT, newdat, by = NULL)
), use.names = TRUE)[ order(Product,Line),]
#     Product  Line        Name Quantity   Unit  Cost
#      <char> <num>      <char>    <int> <char> <num>
#  1: Antonio 10000      Naiara        4     KG   8.0
#  2: Antonio 20000        Toni        7     KG   3.0
#  3: Antonio 30000        Dany       15      L   2.0
#  4:    Pepe 10000       Lucia        4     UD   8.0
#  5:    Pepe 20000    Santiago        7     UD   5.5
#  6:    Pepe 30000 Mariangeles       10     KG   6.0
#  7:    Pepe 40000        Dany       15      L   2.0
#  8:  Vanesa 10000       Lucia        4     UD   8.0
#  9:  Vanesa 20000    Santiago        7     KG   8.0
# 10:  Vanesa 30000        Toni       10     KG   3.0
# 11:  Vanesa 40000       Gines        4     KG   8.0
# 12:  Vanesa 50000        Dany       15      L   2.0

我不知道如何让data.table:::merge.data.table 允许在没有连接键的情况下进行笛卡尔连接,所以我在这里强制使用base-case。作为另一种选择,我可以在两个框架中添加一个虚拟的单值列,然后加入该列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-06
    • 2020-08-03
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 1970-01-01
    • 1970-01-01
    • 2017-05-17
    相关资源
    最近更新 更多