Teradata SQL – 如何将数据在一行中转置

huangapple go评论76阅读模式
英文:

Teradata SQL - How to transpose data in one row

问题

我有一张表如下:

Teradata SQL – 如何将数据在一行中转置

我目前有一个查询,选择 SEQ=450 且 RESULT='LT' 或 SEQ=650 且 RESULT='LT' 的记录。对于特定的 ID,如果存在 SEQ=450 和 SEQ=650 且 RESULT='LT' 的两个序列,我只保留 SEQ=450 和 RESULT='LT' 的行。然而,我想要的最终输出还包括 SEQ 和 CODE 值,这些值来自于 SEQ=450 的上一行,如下所示:

Teradata SQL – 如何将数据在一行中转置

如果仅存在 SEQ=650,则如下:

Teradata SQL – 如何将数据在一行中转置

显然,在这种情况下,我只会选择 seq=450。

我目前的查询是:

CREATE MULTISET VOLATILE TABLE DOM AS (
WITH cte AS (
SELECT DISTINCT ID
FROM MASTER
WHERE SEQ = 450
)

SELECT DISTINCT SCAN.ID, SCAN.SEQ, SCAN.CODE, SCAN.RESULT FROM MASTER 
WHERE (MASTER.SEQ = 450 OR (MASTER.SEQ = 650 AND NOT EXISTS (
SELECT 1 FROM cte WHERE cte.ID = MASTER.ID AND cte.ID = MASTER.ID
))) AND MASTER.RESULT ='LT' 
) WITH DATA PRIMARY INDEX (ID, SEQ) ON COMMIT PRESERVE ROWS;

这给我这个特定 ID 的输出是:

Teradata SQL – 如何将数据在一行中转置

我该如何修改查询以获得其他列呢?注意:SEQ_BEFORE 的值不总是 300 或 600,所以我不能只在查询中使用该序列号作为参考。

英文:

I have a table as below:

Teradata SQL – 如何将数据在一行中转置

I currently have a query that selects records where SEQ=450 and RESULT='LT' OR SEQ=650 and RESULT='LT'. And for a particular ID, if there are both Sequences with 450 and 650 with RESULT='LT' like in this case as shown, I only keep the row with SEQ=450 and RESULT='LT'. However, what I want as a final output is also the SEQ and CODE values from the row above the 450 SEQ. like below

Teradata SQL – 如何将数据在一行中转置

and if only 650 exists for an ID then,

Teradata SQL – 如何将数据在一行中转置

Obviously in this case I would only choose seq=450.

The current query I have is

CREATE MULTISET VOLATILE TABLE DOM AS (
WITH cte AS (
SELECT DISTINCT ID
FROM MASTER
WHERE SEQ = 450
)

SELECT DISTINCT SCAN.ID, SCAN.SEQ, SCAN.CODE, SCAN.RESULT FROM MASTER 
WHERE (MASTER.SEQ = 450 OR (MASTER.SEQ = 650 AND NOT EXISTS (
SELECT 1 FROM cte WHERE cte.ID = MASTER.ID AND cte.ID = MASTER.ID
))) AND MASTER.RESULT ='LT' 
) WITH DATA PRIMARY INDEX (ID, SEQ) ON COMMIT PRESERVE ROWS;

Which gives me the output for this particular ID as:

Teradata SQL – 如何将数据在一行中转置

How can I modify the query to also get the
other columns? Note: The SEQ_BEFORE will not always be 300 or 600, so I cannot just use that seq no. as a reference in the query.

答案1

得分: 0

这是我理解的任务方式:您想获取seq 450和650的数据以及它们的前任值(在您的示例中为seq 300和600)。然后,对于每个ID,您只想选择两者中较小ID的行,因此如果您只找到两个序列450和650中的一个,就显示它,如果两者都存在,就只显示450。

使用LAG获取前任的值。使用MIN OVER获取每个ID的较小seq。

select *
from
(
  select
    id, seq, result, code, 
    lag(code) over (partition by id order by seq) as code_before,
    lag(seq) over (partition by id order by seq) as seq_before
  from mytable
) with_values_before
where seq in (450, 650)
qualify seq = min(seq) over (partition by id)
order by id;
英文:

This is how I understand the task: You want to get the data for seq 450 and 650 along with their predecessor values (seq 300 and 600 in your example) Then per ID you only want to select the row with the lesser ID of the two, so if you find only one of the two sequences 450 and 650, you show it, if there exist both, you only show 450.

Use LAG to get the predecessor's values. Use MIN OVER to get the lesser seq per ID.

select *
from
(
  select
    id, seq, result, code, 
    lag(code) over (partition by id order by seq) as code_before,
    lag(seq) over (partition by id order by seq) as seq_before
  from mytable
) with_values_before
where seq in (450, 650)
qualify seq = min(seq) over (partition by id)
order by id;

huangapple
  • 本文由 发表于 2023年2月7日 01:19:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/75364551.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定