PostgreSQL中的条件累积平均值(Conditional Cumulative Average in PostgreSQL)
我有一个简单的表,它是:
DROP TABLE IF EXISTS running_averages; CREATE TABLE running_averages ( avg_id SERIAL NOT NULL PRIMARY KEY, num1 integer, num2 integer DEFAULT 0 ); INSERT INTO running_averages(num1, num2) SELECT 100, 100 UNION ALL SELECT 200, 175 UNION ALL SELECT -400, NULL UNION ALL SELECT 300, 200 UNION ALL SELECT -100, NULL;
在上表中,如果列“num1”是负值,则应使用前一行的累积平均值更新“num2”列。 我目前的查询是:
SELECT *, num1 * num2 AS current_total, SUM(num1 * num2) OVER(order by avg_id) AS cumulative_sum, SUM(num1) OVER(order by avg_id) AS culmulative_num1, CASE WHEN num1 > 0 THEN SUM(num1 * num2) OVER(order by avg_id) / SUM(num1) OVER(order by avg_id) ELSE 0 END AS cumulative_average FROM running_averages;
结果:
avg_id num1 num2 current_total cumulative_sum cumulative_num1 cumulative_average 1 100 100 10,000 10,000 100 100 2 200 175 35,000 45,000 300 150 3 -400 NULL 45,00 -100 0 4 300 200 60,000 105,000 200 525 5 -100 NULL 105,000 100 0
如果当前行的num1列是负数,我无法弄清楚如何带上一行的累积平均值 。 而不是上述,预期输出应为:
avg_id num1 num2 current_total cumulative_sum cumulative_num1 cumulative_average 1 100 100 10,000 10,000 100 100 2 200 175 35,000 45,000 300 150 3 -400 150 -60,000 -15,00 -100 150 4 300 200 60,000 45,000 200 225 5 -100 225 -22,500 22,500 100 225
在这种情况下,如何获取最后一行的列的值?
编辑:
我编辑了上面的SQL脚本。 我非常喜欢Gordon Linoff的回答。 但是根据脚本的变化,遗憾的是会产生错误的结果:
avg_id num1 num2 new_num2 1 100 100 100 2 200 175 175 3 -400 150 150 (Correct) 4 300 200 200 5 -100 225 50 (Incorrect)
编辑2
我还测试了Multisync的答案,它也产生了错误的结果:
avg_id num1 num2 current_total cumulative_sum cumulative_num1 cumulative_average 1 100 100 10,000 10,000 100 100 2 200 175 35,000 45,000 300 150 3 -400 150 (Correct) -60,000 -15,00 -100 150 4 300 200 60,000 45,000 200 225 5 -100 175 (Incorrect) -17,500 27,500 100 275
编辑3
我接受了Multisync的更新答案,因为它产生了正确的结果。 我还想知道如何改进这样的查询,我们有很多聚合和窗口函数。 有关此主题的任何参考都会有所帮助。
I have a simple table, which is:
DROP TABLE IF EXISTS running_averages; CREATE TABLE running_averages ( avg_id SERIAL NOT NULL PRIMARY KEY, num1 integer, num2 integer DEFAULT 0 ); INSERT INTO running_averages(num1, num2) SELECT 100, 100 UNION ALL SELECT 200, 175 UNION ALL SELECT -400, NULL UNION ALL SELECT 300, 200 UNION ALL SELECT -100, NULL;
In the above table the "num2" column should be updated with the cumulative average of the previous row if the column "num1" is a negative value. My current query is :
SELECT *, num1 * num2 AS current_total, SUM(num1 * num2) OVER(order by avg_id) AS cumulative_sum, SUM(num1) OVER(order by avg_id) AS culmulative_num1, CASE WHEN num1 > 0 THEN SUM(num1 * num2) OVER(order by avg_id) / SUM(num1) OVER(order by avg_id) ELSE 0 END AS cumulative_average FROM running_averages;
The result:
avg_id num1 num2 current_total cumulative_sum cumulative_num1 cumulative_average 1 100 100 10,000 10,000 100 100 2 200 175 35,000 45,000 300 150 3 -400 NULL 45,00 -100 0 4 300 200 60,000 105,000 200 525 5 -100 NULL 105,000 100 0
I cannot figure out the way to bring the cumulative average of the previous row if the current row's num1 column is a negative number. Instead of the above, the expected output should be :
avg_id num1 num2 current_total cumulative_sum cumulative_num1 cumulative_average 1 100 100 10,000 10,000 100 100 2 200 175 35,000 45,000 300 150 3 -400 150 -60,000 -15,00 -100 150 4 300 200 60,000 45,000 200 225 5 -100 225 -22,500 22,500 100 225
How can I get the value of the last row's column in this case?
Edit:
I edited the SQL Script above. I quite like the approach of Gordon Linoff's answer. But it sadly produces incorrect result as per the script change:
avg_id num1 num2 new_num2 1 100 100 100 2 200 175 175 3 -400 150 150 (Correct) 4 300 200 200 5 -100 225 50 (Incorrect)
Edit 2
I also tested answer of Multisync, it also produces wrong result:
avg_id num1 num2 current_total cumulative_sum cumulative_num1 cumulative_average 1 100 100 10,000 10,000 100 100 2 200 175 35,000 45,000 300 150 3 -400 150 (Correct) -60,000 -15,00 -100 150 4 300 200 60,000 45,000 200 225 5 -100 175 (Incorrect) -17,500 27,500 100 275
Edit 3
I have accepted the updated answer of Multisync, since it produces correct results. I would also like to know on how I can improve queries like this where we have a lot of aggregate and window functions. Any reference on this topic will be helpful.
原文:https://stackoverflow.com/questions/26961586
最满意答案
该方法已重命名为
-dateByAddingTimeInterval:
localNotif.fireDate = [now dateByAddingTimeInterval:timeInterval];
在Swift 2.2中:
localNotif.fireDate = now.dateByAddingTimeInterval(timeInterval)
在Swift 3中:
localNotif.fireDate = now.addingTimeInterval(timeInterval) // or simply localNotif.fireDate = now + timeInterval
The method has been renamed to
-dateByAddingTimeInterval:
.localNotif.fireDate = [now dateByAddingTimeInterval:timeInterval];
In Swift 2.2:
localNotif.fireDate = now.dateByAddingTimeInterval(timeInterval)
In Swift 3:
localNotif.fireDate = now.addingTimeInterval(timeInterval) // or simply localNotif.fireDate = now + timeInterval
相关问答
更多-
[self presentModalViewController:pNewController animated:YES]; 可以被替换 [self presentViewController:pNewController animated:YES completion:nil]; WWDC 2012视频会议#236是iOS上视图控制器的发展,可以看到这种变化的背景。 [self presentModalViewController:pNewController animated:YES]; can ...
-
该方法已重命名为-dateByAddingTimeInterval: localNotif.fireDate = [now dateByAddingTimeInterval:timeInterval]; 在Swift 2.2中: localNotif.fireDate = now.dateByAddingTimeInterval(timeInterval) 在Swift 3中: localNotif.fireDate = now.addingTimeInterval(timeInterval) // o ...
-
CLLocationManager的头文件声明您现在应该使用[CLLocationManager isMonitoringAvailableForClass:] : 确定设备是否支持监视指定类型的区域。 如果NO ,则所有尝试监视指定类型的区域都将失败。 你传入你希望监视的CLRegion类。 例如: [CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]]; 编辑:正如@anna在上面提到的,这也在位置和地图编程指南 ...
-
UIPopoverPresentationController在iOS 8 iPhone上(UIPopoverPresentationController on iOS 8 iPhone)[2022-01-14]
您可以使用通过UIPopoverPresentationController.delegate提供的adaptivePresentationStyleForPresentationController:方法来覆盖默认的自适应行为(紧凑的水平环境(即iPhone)中的UIPopoverPresentationController.delegate 。 UIPresentationController使用这种方法来请求使用新的演示风格,在您的情况下,简单地返回UIModalPresentationNone将使U ... -
在iOS 5中使用不推荐的方法(use deprecated methods in iOS 5)[2022-07-09]
使用编译器告诉您不推荐使用的方法的iOS 5设备可能没有问题。 当然,随着时间的推移清除这个问题将是一件好事,因为不推荐使用这些方法,这些方法可能不会在iOS 6中出现(或者不管它会被调用)。 您需要注意的是编译器警告或错误,即对象可能无法响应特定的方法调用。 这些会发生在实际上一直被删除的方法中。 听起来您已经完成了这一步,但请确保您已将SDK设置为XCode中的iOS 5,以确保获得所有错误/警告。 但这里的教训是测试,测试和测试(也在设备上)。 只要你的代码编译并运行在iOS 5上,单独使用不推荐的方 ... -
1)有没有办法让XCode突出显示在以前的操作系统版本中弃用的任何代码? 由于存在表示弃用的C宏,Xcode会自动执行此操作,即: UIKIT_EXTERN NSString *const UIKeyboardBoundsUserInfoKey __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_NA,__MAC_NA,__IPHONE_2_0,__IPHONE_3_2); 2)如果我将目标设置为3.0,并且它编译文件,那是否一定意味着我没有调用任何3.0无法运行的东西 ...
-
我发现了一个类似的问题,假设是的 ,这是处理弃用方法的正确方法, 不 ,没有办法在每个案例的基础上抑制弃用警告,但有些黑客可能会误导编译器。 为了处理示例案例,我决定使用以下方法之一创建一个util类: @protocol UIApplicationDeprecated - (void) setStatusBarHidden:(BOOL)hidden animated:(BOOL)animated; @end @implementation UIUtils + (void) setStatusBar ...
-
如果您打算使用预构建的SLComposeViewController以模态方式呈现视图以便在Twitter上进行共享,您可以使用类似这样的内容 //Check for Social Framework availability (iOS 6) if(NSClassFromString(@"SLComposeViewController") != nil){ if([SLComposeViewController instanceMethodForSelector:@selector(isAvail ...
-
由于AlAsset库需要启用位置服务,因此我无法忽略位置检查。 由于iOS 6.0用户甚至可以阻止应用程序访问照片库,因此也需要AssetLibrary授权。 我的解决方案是在下面的委托中使用[self.locMgr stopUpdatingLocation]: - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { if(sta ...
-
H2CO3是非常正确的:不使用已弃用功能的原因是,Apple已经给我们公平的警告,即将被弃用的iOS版本可能不支持它,因此,您的应用可能无法在未来版本的iOS上使用。 新的presentViewController为您提供了弃用方法的所有功能,并为您提供了completion块的选项。 也许你不需要(在这种情况下,你只是通过nil ),但没有理由使用已弃用的功能。 如果您计划在新方法所要求的iOS版本(本例中为iOS 5)之前规划支持iOS,则只应使用已弃用的方法;如果您这样做,则应该仅针对那些较旧的方法有 ...