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

由于存在不相关的字段而导致交叉表拆分结果

戎泰
2023-03-14
问题内容

我正在将postgres 9.1与tablefunc:crosstab一起使用

我有一个具有以下结构的表:

CREATE TABLE marketdata.instrument_data
(
  dt date NOT NULL,
  instrument text NOT NULL,
  field text NOT NULL,
  value numeric,
  CONSTRAINT instrument_data_pk PRIMARY KEY (dt , instrument , field )
)

这由每天获取数据的脚本填充。因此可能看起来像这样:

| dt         | instrument        | field     | value |
|------------+-------------------+-----------+-------|
| 2014-05-23 | SGX.MiniJGB.2014U | PX_VOLUME | 1     |
| 2014-05-23 | SGX.MiniJGB.2014U | OPEN_INT  | 2     |

然后,我使用以下交叉表查询来透视表:

select dt, instrument, vol, oi 
FROM crosstab($$
    select dt, instrument, field, value 
    from marketdata.instrument_data 
    where field = 'PX_VOLUME' or field = 'OPEN_INT'
    $$::text, $$VALUES ('PX_VOLUME'),('OPEN_INT')$$::text
) vol(dt date, instrument text, vol numeric, oi numeric);

运行这个我得到结果:

| dt         | instrument        | vol | oi |
|------------+-------------------+-----+----|
| 2014-05-23 | SGX.MiniJGB.2014U | 1   | 2  |

问题: 在表中使用大量实际数据运行时,我注意到对于某些字段,该函数将结果分为两行:

| dt         | instrument        | vol | oi |
|------------+-------------------+-----+----|
| 2014-05-23 | SGX.MiniJGB.2014U | 1   |    |
| 2014-05-23 | SGX.MiniJGB.2014U |     | 2  |

我检查了dt和instrument字段是否相同,并通过将交叉表的输出分组来产生了解决方法。

分析 我发现,输入表中存在另一个条目会导致输出分成两行。如果我有如下输入:

| dt         | instrument        | field     | value |
|------------+-------------------+-----------+-------|
| 2014-04-23 | EUX.Bund.2014M    | PX_VOLUME | 0     |
| 2014-05-23 | SGX.MiniJGB.2014U | PX_VOLUME | 1     |
| 2014-05-23 | SGX.MiniJGB.2014U | OPEN_INT  | 2     |

我得到:

| dt         | instrument        | vol | oi |
|------------+-------------------+-----+----|
| 2014-04-23 | EUX.Bund.2014M    | 0   |    |
| 2014-05-23 | SGX.MiniJGB.2014U | 1   |    |
| 2014-05-23 | SGX.MiniJGB.2014U |     | 2  |

真的很奇怪…

如果我手动重新创建上述输入表,则输出将如我们期望的那样,合并为一行。

如果我运行:

update marketdata.instrument_data 
set instrument = instrument 
where instrument = 'EUX.Bund.2014M'

再说一次,输出就如我们所期望的那样,这令人惊讶,因为我所做的只是将instrument字段设置为其自身。

因此,我只能得出这样的结论:在该Bund条目中存在一些隐藏的字符/编码问题,该问题打破了交叉表。

关于如何确定中断交叉表的条目有什么建议吗?

编辑:我在原始表上运行以下内容,尝试查看任何隐藏的字符:

select instrument, encode(instrument::bytea, 'escape')  
from marketdata.bloomberg_future_data_temp 
where instrument = 'EUX.Bund.2014M';

并得到:

| instrument     | encode         |
|----------------+----------------|
| EUX.Bund.2014M | EUX.Bund.2014M |

问题答案:

两个问题。

1. ORDER BY 是必需的。

手册:

在实践中,SQL查询应始终指定ORDER BY 1,2以确保输入行的顺序正确,即,具有相同值的值row_name在该行内被放在一起并正确地排序。

对于的单参数形式crosstab()ORDER BY 1,2将是必需的。

2. 列,每组具有不同的值。

手册:

crosstab(text source_sql, text category_sql)
source_sql是产生数据源集的SQL语句。

此语句必须返回
row_name列,一category列和一value列。它还可能有一个或多个“额外”列。该row_name列必须是第一列。在categoryvalue列必须是最后两列的顺序。row_name
与之间的任何列category均被视为“额外”。对于具有相同row_name值的所有行,“额外”列应相同。


大胆强调我的。 栏。似乎您想在 列上形成组,但并没有按您希望的那样工作。

解决方案取决于您实际想要实现的目标。这不是您的问题,您默默地假定该功能将实现您希望的功能。

解决方案

我想您想在两个主要专栏上进行分组:(dt, instrument)。您可以使用串联或数组来玩技巧,但这会很慢和/或不可靠。我建议使用窗口函数
rank()
dense_rank()
更干净,更快速的方法,或者为 每个所需的组 生成一个 单列唯一值 。这 非常
便宜,因为排序行是主要成本,并且框架的顺序无论如何都与所需顺序相同。如果需要,可以在外部查询中删除添加的列:

SELECT dt, instrument, vol, oi
FROM   crosstab(
   $$SELECT dense_rank() OVER (ORDER BY dt, instrument) AS rnk
          , dt, instrument, field, value 
     FROM   marketdata.instrument_data 
     WHERE  field IN ('PX_VOLUME', 'OPEN_INT')
     ORDER  BY 1$$
 , $$VALUES ('PX_VOLUME'),('OPEN_INT')$$
   ) vol(rnk int, dt date, instrument text, vol numeric, oi numeric);


 类似资料:
  • 问题内容: 在我们的项目中,我们在单独的Maven模块中具有Service和DAO层。服务模块取决于DAO模块,并与它的实体一起使用。问题在于我们不能在DAO实体中放置使用服务层中某些服务的定制jsr 303约束,因为这会创建从DAO层到服务层的反向引用,因为验证器类需要在custom的validatedBy属性中进行引用@约束。 有没有办法(使用标准jsr 303 api)在运行时指定一些自定义

  • 我正在努力实现调车场算法来评估简单的表达式。代码似乎可以工作,但如果有空格就会崩溃。这是令人惊讶的,因为有一个特定的空白检查似乎根本没有抓住它。 例如,给出了结果,但导致分段错误。有什么想法吗? 旁白:调车场算法将中缀转换为后缀符号。所以严格地说,修改算法以实际计算表达式是很常见的,但它仍然是调车场算法吗?对于普通算法,是否还需要另一个算法以后缀符号计算表达式?

  • 当我创建新的团队并试图将其关联到我的用户配置文件时,我发现这个错误正在显示。我想要一个团队,很多成员和只有一个创建者(或管理的团队),创建者也是小组的成员。如何将团队与用户配置文件关联? models.py views.py

  • 我有一个数据库(和模型)情况,如下模式所示: 这是ModelSerialize: 我将这个json发送到api方法 视图中我的post_create实现: 更新 现在我得到了这个错误:django.db.models.fields.related_descriptors.relatedObjectDoesNotexist:Post没有ID。 这些是我的模型: 类PostCategory(Model

  • 问题内容: 我有一个经典的Java EE系统,具有JSF的Web层,用于BL的EJB 3和用于对DB2数据库进行数据访问的Hibernate 3。我在以下情况下苦苦挣扎:用户将启动一个过程,该过程涉及从数据库中检索大型数据集。检索过程花费一些时间,因此用户不会立即收到响应,变得不耐烦,并打开新的浏览器并再次启动检索,有时是多次。EJB容器显然没有意识到第一次检索不再相关的事实,并且当数据库返回结果

  • 我需要知道如何清除导致以下错误的未保存的相关数据: 禁止保存()以防止由于未保存的相关对象'order'而导致数据丢失。 我的代码按预期工作,但我未能完成一个订单。此后,任何保存新订单的尝试都会导致上述错误。我知道原因是对的更改,但肯定有一些方法可以通过日志之类的方式清除这些更改...我尝试重新创建数据库和sqlflush命令,但都不起作用。 视图 模型 表格