当前位置: 首页 > 面试题库 >

SQL难题/难题:给定堆栈跟踪-如何在每个时间点查找顶部元素?

鲜于意
2023-03-14
问题内容
  • 我现实生活中的用例是合并嵌套范围。我画了一些草图,然后看到了开始和结束堆栈PUSH和POP操作的范围之间的相似之处。我知道解决这个问题也可以解决原来的问题。
  • 柱实际上可以从问题中移除。当val为NULL时,它是POP操作,否则是PUSH操作。

stack_trace 包含以下列:

  • i-表示时间点的整数值。
  • op-2种可能的操作: I (“输入” /“推”)和 O (“输出” /“弹出”)。
  • val-由“ in” /“ push”操作插入的值,对于“ out” /“ pop”操作插入NULL。

目的是在每个时间点( i )找出堆栈顶部的值。

例如

(NULL值在这里表示为空白)

数据:

i   op  val 
--  --  --  
1   I   A   
2   I   B   
3   O
4   I   C
5   O    
6   O

所需结果:

i   top_of_stack_val
--  ----------------
1   A
2   B
3   A
4   C
5   A
6

要求

  • 解决方案应该是单个SQL查询(可以使用子查询)。
  • 仅允许以下子句: SELECTFROMWHEREGROUP BYHAVINGORDER BY
  • 不允许* 使用 WITH 子句(CTE-公共表html" target="_blank">表达式)。 *
  • 不允许 使用T-SQL,PL / SQL等。
  • 不允许 使用UDF(用户定义的函数)。
  • 不允许 使用变量。

样本数据

create table stack_trace
(
    i       int
   ,op      char(1)
   ,val     char(1)
)
;

insert into stack_trace (i,op,val) values (1,'I','A');
insert into stack_trace (i,op,val) values (2,'I','B');
insert into stack_trace (i,op,val) values (3,'I','C');
insert into stack_trace (i,op,val) values (4,'I','D');
insert into stack_trace (i,op,val) values (5,'I','E');
insert into stack_trace (i,op)     values (6,'O');
insert into stack_trace (i,op)     values (7,'O');
insert into stack_trace (i,op)     values (8,'O');
insert into stack_trace (i,op,val) values (9,'I','F');
insert into stack_trace (i,op)     values (10,'O');
insert into stack_trace (i,op,val) values (11,'I','G');
insert into stack_trace (i,op,val) values (12,'I','H');
insert into stack_trace (i,op)     values (13,'O');
insert into stack_trace (i,op)     values (14,'O');
insert into stack_trace (i,op,val) values (15,'I','I');
insert into stack_trace (i,op,val) values (16,'I','J');
insert into stack_trace (i,op,val) values (17,'I','K');
insert into stack_trace (i,op,val) values (18,'I','L');
insert into stack_trace (i,op,val) values (19,'I','M');
insert into stack_trace (i,op)     values (20,'O');
insert into stack_trace (i,op,val) values (21,'I','N');
insert into stack_trace (i,op)     values (22,'O');
insert into stack_trace (i,op,val) values (23,'I','O');
insert into stack_trace (i,op)     values (24,'O');
insert into stack_trace (i,op,val) values (25,'I','P');
insert into stack_trace (i,op)     values (26,'O');
insert into stack_trace (i,op)     values (27,'O');
insert into stack_trace (i,op,val) values (28,'I','Q');
insert into stack_trace (i,op,val) values (29,'I','R');
insert into stack_trace (i,op)     values (30,'O');
insert into stack_trace (i,op)     values (31,'O');
insert into stack_trace (i,op)     values (32,'O');
insert into stack_trace (i,op)     values (33,'O');
insert into stack_trace (i,op)     values (34,'O');
insert into stack_trace (i,op)     values (35,'O');
insert into stack_trace (i,op,val) values (36,'I','S');
insert into stack_trace (i,op)     values (37,'O');
insert into stack_trace (i,op)     values (38,'O');
insert into stack_trace (i,op,val) values (39,'I','T');
insert into stack_trace (i,op,val) values (40,'I','U');
insert into stack_trace (i,op)     values (41,'O');
insert into stack_trace (i,op,val) values (42,'I','V');
insert into stack_trace (i,op,val) values (43,'I','W');
insert into stack_trace (i,op,val) values (44,'I','X');
insert into stack_trace (i,op)     values (45,'O');
insert into stack_trace (i,op)     values (46,'O');
insert into stack_trace (i,op,val) values (47,'I','Y');
insert into stack_trace (i,op)     values (48,'O');
insert into stack_trace (i,op)     values (49,'O');
insert into stack_trace (i,op,val) values (50,'I','Z');
insert into stack_trace (i,op)     values (51,'O');
insert into stack_trace (i,op)     values (52,'O');

所需结果

i   top_of_stack_val
--  ----------------
1   A
2   B
3   C
4   D
5   E
6   D
7   C
8   B
9   F
10  B
11  G
12  H
13  G
14  B
15  I
16  J
17  K
18  L
19  M
20  L
21  N
22  L
23  O
24  L
25  P
26  L
27  K
28  Q
29  R
30  Q
31  K
32  J
33  I
34  B
35  A
36  S
37  A
38  
39  T
40  U
41  T
42  V
43  W
44  X
45  W
46  V
47  Y
48  V
49  T
50  Z
51  T
52

问题答案:

我个人认为,您最终会发现只能在所有SQL
Server,Teradata,Postgres和Oracle中使用的SQL,并且如果表很大的话,它们是否具有可接受的性能。

一个SQL Server解决方案(演示)如下

SELECT i,
       SUBSTRING(MAX(FORMAT(i, 'D10') + val) OVER (PARTITION BY Pos ORDER BY i 
                                                     ROWS UNBOUNDED PRECEDING), 11, 8000)
FROM   (SELECT st.*,
               sum(CASE WHEN op = 'I' THEN 1 ELSE -1 END) 
                  OVER (ORDER BY i ROWS UNBOUNDED PRECEDING) AS pos
        FROM   stack_trace st) t1
ORDER  BY i;


 类似资料:
  • 问题内容: 程序中没有单个方法“知道”它在堆栈中的位置。它所知道的只是它自己的小工作,它完成了并返回了。因此,当引发异常并打印堆栈跟踪时,它是从哪里来的? 在JVM中监视程序状态的每个应用程序旁边隐式地运行着一个单独的线程吗?还是JVM本身保存此信息,并且在抛出异常时以某种方式从异常中提取数据? 如果是上述两种情况之一,是否可以使用某些调用来检索堆栈跟踪(从监视器线程或JVM) 而不会 引发异常?

  • 当Xdebug被激活时,只要PHP决定显示通知,警告,错误等,就会显示堆栈跟踪。堆栈跟踪显示的信息以及显示方式可以根据您的需要进行配置。 Xdebug在错误情况下显示的堆栈跟踪信息量相当保守(如果display.errors 在php.ini中设置为On)。这是因为大量的信息会减慢脚本的执行速度和浏览器中堆栈跟踪本身的渲染速度。但是,可以使堆栈轨迹以不同的设置显示更详细的信息。 堆栈跟踪中的变量

  • 问题内容: 在Java中,如果一个方法抛出错误,则调用它的方法可以将其传递给下一个方法。 我正在迅速编写一个应用程序,并且希望做同样的事情。这可能吗?如果不可能,还有哪些其他可能的解决方案?我进行调用的原始函数具有此结构。 问题答案: 参考Swift- 错误处理文档 ,您应该: 1- 通过声明符合错误协议的 枚举 来创建自定义错误类型: 2- 声明为可抛出函数: 3- 声明为throwable函数

  • 问题内容: 在Java中,是否有任何方法可以查看完整的,未截断的堆栈跟踪(例如,通过增加记录的帧数),或者以其他方式查看堆栈跟踪的 底部 ?通常,堆栈跟踪会从顶部截断为1024帧,但是对于堆栈溢出问题,这是毫无价值的,因为您确实需要查看是谁触发了触发递归的调用,位于底部附近。在堆栈 中间 截断会更好,但是显然Sun的JVM不够聪明。 也许甚至一些特定于Sun的特殊标志?我尝试将堆栈大小减小到最小允

  • 我有一个使用jquery FullCalendar构建的日历应用程序。用户查看他们本地时区中的事件,我的服务器将它们存储为MySQL中的UTC日期时间。(关于stackoverflow的其他问题表明,这是处理时区的最佳方法。)因此,每次用户在日历上保存或查看事件时都会进行转换。这很好,但我对如何最好地处理夏令时感到困惑。 例如,假设timezone EST(东部标准时间)中的一个用户在不是夏时制的

  • 问题内容: 更新 :Intellij IDEA的最新版本完全实现了我想要的功能。问题是如何在IDE外部实现此功能(以便我可以将异步堆栈跟踪信息转储到日志文件中),理想情况下无需使用检测代理。 自从我将应用程序从同步模型转换为异步模型以来,调试故障一直遇到问题。 当我使用同步API时,我总是在异常stacktraces中找到我的类,因此我知道从哪里开始寻找问题。使用异步API,我得到的堆栈跟踪既不引