我有一个表格,其中包含每个设备的几个测试的测量信息:

  • Device_id提供了有关哪个设备进行了测试的信息
  • MEASURATION_NO是一个递增数字,给出了执行测试的顺序
  • 测试为您提供执行的测试的名称
  • IS_LAST_MEASURATION_ON_TEST是一个布尔型字段,提供特定行是否为测试的最后测量结果的信息.如果该行是特定测试的设备的最后一行,则返回TRUE.如果同一设备的后续行用于相同的测试,则返回FALSE.
  • OK提供测试正常(=真)或不正常(=假)的信息
  • 如果ok=FALSE,则ERROR_CODE会给出特定的错误代码;如果OK=TRUE,则会给出0
WITH measurements (device_id,measurement_no,test,is_last_measurement_on_test,ok,error_code) AS ( VALUES
  -- case 1: all measurements good, expecting to show test 3 only
  ('d1',1,'test1',true,true,0),
  ('d1',2,'test2',true,true,0),
  ('d1',3,'test3',true,true,0),
  -- case 2: test 2, expecting to show test 2 only
  ('d2',1,'test1',true,true,0),
  ('d2',2,'test2',true,false,100),
  ('d2',3,'test3',true,true,0),
  -- case 3: test 2 und 3 bad, expecting to show test 2 only
  ('d3',1,'test1',true,true,0),
  ('d3',2,'test2',true,false,100),
  ('d3',3,'test3',true,false,200),
  -- case 4: test 2 bad on first try, second time good, expecting to show test 3 only
  ('d4',1,'test1',true,true,0),
  ('d4',2,'test2',false,false,100),
  ('d4',3,'test2',true,true,0),
  ('d4',4,'test3',true,true,0)
)
select * from measurements
where is_last_measurement_on_test=true

现在,我想根据每个设备的以下条件来筛选这些行:

  • 只应考虑每个测试上的最后一次测量->这很简单:筛选IS_LAST_MEASURATION_ON_TEST=TRUE
  • 对于每个设备:如果在IS_LAST_MEASURATION_ON_TEST=TRUE的任何测试中出现错误结果(ok=FALSE),我希望显示设备失败的第一个测试.
  • 对于每个设备:如果在IS_LAST_MEASURATION_ON_TEST=TRUE的任何测试中没有任何坏结果(ok=TRUE),我希望显示设备通过的最后一次测试.

对于上面的给定示例,我希望只显示以下行:

  ('d1',3,'test3',true,true,0) 
  ('d2',2,'test2',true,false,100)
  ('d3',2,'test2',true,false,100)
  ('d4',4,'test3',true,true,0)

我怎么才能收到这个结果呢?我已经try 了很多次使用first_value,例如

first_value(nullif(error_code,0)) over (partition by device_id)

但我没能以我想要的方式处理它.

推荐答案

拥有以下示例数据:

CREATE TABLE measurements (
  device_id text,
  measurement_no integer,
  test text,
  is_last_measurement_on_test boolean,
  ok boolean,
  error_code integer
);

INSERT INTO measurements (device_id, measurement_no, test, is_last_measurement_on_test, ok, error_code)
VALUES
  ('d1', 1, 'test1', true, true, 0),
  ('d1', 2, 'test2', true, true, 0),
  ('d1', 3, 'test3', true, true, 0),
  ('d2', 1, 'test1', true, true, 0),
  ('d2', 2, 'test2', true, false, 100),
  ('d2', 3, 'test3', true, true, 0),
  ('d3', 1, 'test1', true, true, 0),
  ('d3', 2, 'test2', true, false, 100),
  ('d3', 3, 'test3', true, false, 200),
  ('d4', 1, 'test1', true, true, 0),
  ('d4', 2, 'test2', false, false, 100),
  ('d4', 3, 'test2', true, true, 0),
  ('d4', 4, 'test3', true, true, 0);

它将如下所示:

WITH DataSource AS
(
  SELECT *
       ,MIN(CASE WHEN ok = false THEN test END) OVER (PARTITION BY device_id) AS first_failed_test
       ,ROW_NUMBER() OVER (PARTITION BY device_id ORDER BY test DESC) AS test_id
  FROM measurements
  WHERE is_last_measurement_on_test = true
)
SELECT device_id, measurement_no, test, is_last_measurement_on_test, ok, error_code
FROM DataSource
WHERE (first_failed_test IS NULL and test_id = 1)
    OR (first_failed_test = test)

enter image description here

其思想是获取第一个失败测试的名称,并使用从最新测试开始的ROW_NUMBER对测试进行排序.

重要的是,我在这里按照他们的名字来排序测试.在您的实际场景中,我猜您有一个Records_id或日期,可以用它来做这件事.因此,您需要稍微更改一下代码.

Sql相关问答推荐

SQL查询以条件空值跟踪生产操作结果进展

使用sede获取不一定有两个不同标签的所有问题

我怎样才能得到列值对应的最大值在另一个?

查询每周数据(周一至周日),避免年度日期重叠

snowflake/SQL嵌套的JSON对象和数组

Oracle 23c ROUND,数据类型为DATE

将伪数据插入Postgres表

从每月生成的系列中生成每日汇率

连续天跟踪购买情况(将标记返回到另一列?)

POSTGRES to_timestamp() 假定 UTC 字符串为本地时间

试图找到两个身份列表的交集(列表的长度不同),但获取列 id 不明确?

基于变量的条件 WHERE 子句

SQL 将 Varchar 转换为日期

复制SQL Server临时表

如何在 ClickHouse SQL 中使用 CTE 将邻居语句中的数字作为偏移量传递?

更新表 A,然后将新值插入表 B(包含更新内容的历史日志(log))

在多个表上递归查找

在 PostgreSQL 中使用重音敏感排序进行重音不敏感搜索

As400 (IBM i) SQL 表 QSYS2.SYSTABLES 上的元数据

如何在 Oracle 中获取此变量的值?