如何根据分组填充字段?

时间:2017-08-30 15:02:08

标签: sql powershell

我正在尝试创建一个PowerShell(5.1)脚本(使用SSMS和SQL Server 2014打开SQL建议),以消除手动更新以CSV格式导出的大型数据文件。

以下是需要更新的原始数据集:

Parent ID | Parent Owner | Sub ID | Sub Owner | Sub Hours
A                          aA       Rob Green   0
A                          aB       Rob Green   6
B                          aA       Jane Doe    4
B                          aB       Jane Doe    10
B                          aC       Bob Smith   18
C                          cA       Jane Doe    0
C                          cB       Jane Doe    6
D                          dA       Bob Smith   0
D                          dB       Bob Smith   6
E                          dE       Joe Brown   0

如您所见,父ID可以有一个或多个子所有者和子ID。

我的目标是根据以下标准填充“父级所有者”字段:

对于每个家长ID

  1. 如果只有一个不同的子所有者,则该子所有者应该是所有相应父ID的父所有者。
  2. 如果只出现一次父ID,则该子所有者应该是该父ID的父所有者。
  3. 如果父母ID有多个子所有者,则具有最高总计子小时数的子所有者应该是该父母ID每次出现的父所有者。
  4. 为了澄清,该标准适用于上述原始数据,如下所示:

    • 父ID“A”适用于条件1
    • 父母ID“B”适用于条件3
    • 父ID“C”适用于条件1
    • 父ID“D”适用于条件1
    • 父母ID“E”适用于标准2

    我希望上面的数据在完成后看起来像是这样的:

    Parent ID | Parent Owner | Sub ID | Sub Owner | Sub Hours
    A           Rob Green      aA       Rob Green   0
    A           Rob Green      aB       Rob Green   6
    B           Bob Smith      aA       Jane Doe    4
    B           Bob Smith      aB       Jane Doe    10
    B           Bob Smith      aC       Bob Smith   18
    C           Jane Doe       cA       Jane Doe    0
    C           Jane Doe       cB       Jane Doe    6
    D           Bob Smith      dA       Bob Smith   0
    D           Bob Smith      dB       Bob Smith   6
    E           Joe Brown      dE       Joe Brown   0
    

    我最大的困难是标准3.我无法理解如何做到这一点。谁能让我知道如何使用PS或SQL获得预期的输出?

    任何帮助都会非常感激!

1 个答案:

答案 0 :(得分:1)

我发誓我自己对SQL严格禁忌。但是,以下是纯PowerShell解决方案的示例(而且我很确定它可以简单地转换为SQL):

# mimic SQL output
$SqlOutput = @"
Parent ID|Parent Owner|Sub ID|Sub Owner|Sub Hours
A||aA|Rob Green|0
A||aB|Rob Green|6
B||aA|Jane Doe|4
B||aB|Jane Doe|10
B||aC|Bob Smith|18
C||cA|Jane Doe|0
C||cB|Jane Doe|6
D||dA|Bob Smith|0
D||dB|Bob Smith|6
E||dE|Joe Brown|0
"@ | ConvertFrom-Csv -Delimiter '|'

# compute an auxiliary variable
$SqlOutputGroups = $SqlOutput | 
    Group-Object -Property 'Parent ID', 'Sub Owner' | 
      ForEach-Object { 
        New-Object psobject -Property @{
          'Parent ID' = ( $_.Name -split ', ')[0]
          'Sub Owner' = ( $_.Name -split ', ')[1]
          Hours = ( $_.Group | 
            Measure-Object -Property 'Sub Hours' -Sum).Sum
        }
      } 

# compute Criterium3  as a hashtable
$SqlOutputCriterium3 = @{}
$SqlOutputGroups | Group-Object -Property 'Parent ID' |
    ForEach-Object {
        $SqlOutputCriterium3[$_.Name] = ($_.Group | 
            Sort-Object -Property Hours |
                Select-Object -Last 1).'Sub Owner'
    }

# apply Criterium3
$SqlOutput | ForEach-Object {
    $_.'Parent Owner' = $SqlOutputCriterium3.$($_.'Parent ID')
}

# show result in a table format
$SqlOutput | Format-Table -AutoSize 

输出D:\PShell\SO\45963820.ps1

Parent ID Parent Owner Sub ID Sub Owner Sub Hours
--------- ------------ ------ --------- ---------
A         Rob Green    aA     Rob Green 0        
A         Rob Green    aB     Rob Green 6        
B         Bob Smith    aA     Jane Doe  4        
B         Bob Smith    aB     Jane Doe  10       
B         Bob Smith    aC     Bob Smith 18       
C         Jane Doe     cA     Jane Doe  0        
C         Jane Doe     cB     Jane Doe  6        
D         Bob Smith    dA     Bob Smith 0        
D         Bob Smith    dB     Bob Smith 6        
E         Joe Brown    dE     Joe Brown 0

请注意, Criterium 3 涵盖了条件 1 2 ,但不够 >如果更多的 Sub Owners 对于特定的 Parent ID 具有最高的 Sub Hours 总和(例如,如果使用B||aA|Jane Doe|8,上例中B||aA|Jane Doe|4中的,那么 Jane Doe 的总和为 Sub Hours = 18,而 Bob Smith 父母ID = B)。