SQL - 分区依据或循环以从主 table 创建子 table
SQL - Partition By or Loop to create sub table from master table
我创建了一个master table 运行 这个查询:
硕士Table
WITH cfr_pr_audit AS
(WITH cfr_pr AS
(SELECT
ROW_NUMBER() OVER (ORDER BY id ASC) AS id_seq,
id,
status AS pr_status
FROM infrabi_stg.o_infr_dly_cfr_purchase_request
WHERE snapshot_day = (SELECT max(snapshot_day) FROM infrabi_stg.o_infr_dly_cfr_purchase_request)),
cfr_pr_audit_pre AS
(SELECT
purchase_request,
status AS audit_status,
created_by,
created_at
FROM infrabi_stg.o_infr_dly_cfr_purchase_request_audit
WHERE snapshot_day = (SELECT max(snapshot_day) FROM infrabi_stg.o_infr_dly_cfr_purchase_request_audit)
ORDER BY created_at DESC)
SELECT *,
ROW_NUMBER() OVER (PARTITION BY cfr_pr.id,cfr_pr_audit_pre.audit_status ORDER BY created_at DESC) AS row_seq
FROM cfr_pr LEFT JOIN cfr_pr_audit_pre ON cfr_pr.id = cfr_pr_audit_pre.purchase_request
ORDER BY cfr_pr_audit_pre.created_at DESC)
此查询 returns 每个 ID 的多条记录 - 每个 ID 大约有 9-11 行,具有不同的审计状态和日期。 (下图是每个 id 的行示例)
我正在尝试创建一个查询,该查询将创建一个新的 table,每个 ID 将有 1 行,并将合并主 table 中每个 ID 的不同详细信息(换句话说从 master table 的每个 id 的 9-11 行中选择特定信息,并为每个 id 创建一行)。
我试图在新的 table 中提取每个 ID 的信息是这样的:
每个 id 提取的信息
SELECT DISTINCT
(SELECT id FROM cfr_pr_audit WHERE created_at = (SELECT MIN(created_at) FROM cfr_pr_audit WHERE id = '306637') AND id = '306637') AS purchase_request,
(SELECT MIN(created_at) FROM cfr_pr_audit WHERE id = '306637') AS created_at,
(SELECT created_by FROM cfr_pr_audit WHERE created_at = (SELECT MIN(created_at) FROM cfr_pr_audit WHERE id = '306637') AND id = '306637') AS created_by,
(SELECT created_at FROM cfr_pr_audit WHERE created_at = (SELECT created_at FROM cfr_pr_audit WHERE audit_status = 'Status 8' AND row_seq = 1 AND id = '306637') AND NOT pr_status = 'NO PLACED' AND id = '306637') AS submitted_at,
(SELECT created_by FROM cfr_pr_audit WHERE created_at = (SELECT created_at FROM cfr_pr_audit WHERE audit_status = 'Status 8' AND row_seq = 1 AND id = '306637') AND NOT pr_status = 'NO PLACED' AND id = '306637') AS submitted_by,
ISNULL((SELECT created_at FROM cfr_pr_audit WHERE audit_status = 'Status 9' AND row_seq = 1 AND id = '306637'),(SELECT created_at FROM cfr_pr_audit WHERE audit_status = 'Status 10' AND row_seq = 1 AND id = '306637')) AS approved_at,
(SELECT created_at FROM cfr_pr_audit WHERE audit_status = 'Status 11' AND row_seq = 1 AND id = '306637') AS po_created_at
FROM cfr_pr_audit
以上查询适用于一个特定的 ID(我选择的那个 - 363114)。
我怎样才能使它适用于所有 ID?有点像通过不同 ID 的循环。
我尝试了以下选项:
选项 1:
SELECT DISTINCT
id AS purchase_request,
MIN(created_at) OVER (PARTITION BY id) AS created_at
FROM cfr_pr_audit
分区依据是最合乎逻辑的方法(我通常使用的方法),但是我被困在我试图获得的第三个值
(SELECT created_by FROM cfr_pr_audit WHERE created_at = (SELECT MIN(created_at) FROM cfr_pr_audit WHERE id = '363114') AND id = '363114') AS created_by
因为我在这里找不到 PARTITION BY 的方法。其余行也是如此——MIN(created_at) 是我唯一可以按(第二个值)
划分的部分
选项2:
我想过做一些类似循环的事情
DECLARE @i INT = 0
SELECT @count = MAX(id_seq) FROM cfr_pr_audit
WHILE @i <= @count
BEGIN
SET @i = @i + 1;
MIN(created_at) OVER (PARTITION BY purchase_request) AS created_at
END
但不确定这是否可行并创建一个统一的 table 以及这是否有效。
非常感谢任何提示。
您可以将条件聚合与 window 函数一起使用:
SELECT DISTINCT id AS purchase_request,
MIN(created_at) OVER (PARTITION BY id) AS created_at,
FIRST_VALUE(created_by) OVER (PARTITION BY id ORDER BY created_at) AS created_by,
MAX(CASE WHEN audit_status = 'Status 8' AND row_seq = 1 AND pr_status <> 'NO PLACED' THEN created_at END) OVER (PARTITION BY id) AS submitted_at,
MAX(CASE WHEN audit_status = 'Status 8' AND row_seq = 1 AND pr_status <> 'NO PLACED' THEN created_by END) OVER (PARTITION BY id) AS submitted_by,
ISNULL(MAX(CASE WHEN audit_status = 'Status 9' AND row_seq = 1 THEN created_at END) OVER (PARTITION BY id),
MAX(CASE WHEN audit_status = 'Status 10' AND row_seq = 1 THEN created_at END) OVER (PARTITION BY id)) AS approved_at,
MAX(CASE WHEN audit_status = 'Status 11' AND row_seq = 1 THEN created_at END) OVER (PARTITION BY id) AS po_created_at
FROM cfr_pr_audit
我创建了一个master table 运行 这个查询:
硕士Table
WITH cfr_pr_audit AS
(WITH cfr_pr AS
(SELECT
ROW_NUMBER() OVER (ORDER BY id ASC) AS id_seq,
id,
status AS pr_status
FROM infrabi_stg.o_infr_dly_cfr_purchase_request
WHERE snapshot_day = (SELECT max(snapshot_day) FROM infrabi_stg.o_infr_dly_cfr_purchase_request)),
cfr_pr_audit_pre AS
(SELECT
purchase_request,
status AS audit_status,
created_by,
created_at
FROM infrabi_stg.o_infr_dly_cfr_purchase_request_audit
WHERE snapshot_day = (SELECT max(snapshot_day) FROM infrabi_stg.o_infr_dly_cfr_purchase_request_audit)
ORDER BY created_at DESC)
SELECT *,
ROW_NUMBER() OVER (PARTITION BY cfr_pr.id,cfr_pr_audit_pre.audit_status ORDER BY created_at DESC) AS row_seq
FROM cfr_pr LEFT JOIN cfr_pr_audit_pre ON cfr_pr.id = cfr_pr_audit_pre.purchase_request
ORDER BY cfr_pr_audit_pre.created_at DESC)
此查询 returns 每个 ID 的多条记录 - 每个 ID 大约有 9-11 行,具有不同的审计状态和日期。 (下图是每个 id 的行示例)
我正在尝试创建一个查询,该查询将创建一个新的 table,每个 ID 将有 1 行,并将合并主 table 中每个 ID 的不同详细信息(换句话说从 master table 的每个 id 的 9-11 行中选择特定信息,并为每个 id 创建一行)。
我试图在新的 table 中提取每个 ID 的信息是这样的:
每个 id 提取的信息
SELECT DISTINCT
(SELECT id FROM cfr_pr_audit WHERE created_at = (SELECT MIN(created_at) FROM cfr_pr_audit WHERE id = '306637') AND id = '306637') AS purchase_request,
(SELECT MIN(created_at) FROM cfr_pr_audit WHERE id = '306637') AS created_at,
(SELECT created_by FROM cfr_pr_audit WHERE created_at = (SELECT MIN(created_at) FROM cfr_pr_audit WHERE id = '306637') AND id = '306637') AS created_by,
(SELECT created_at FROM cfr_pr_audit WHERE created_at = (SELECT created_at FROM cfr_pr_audit WHERE audit_status = 'Status 8' AND row_seq = 1 AND id = '306637') AND NOT pr_status = 'NO PLACED' AND id = '306637') AS submitted_at,
(SELECT created_by FROM cfr_pr_audit WHERE created_at = (SELECT created_at FROM cfr_pr_audit WHERE audit_status = 'Status 8' AND row_seq = 1 AND id = '306637') AND NOT pr_status = 'NO PLACED' AND id = '306637') AS submitted_by,
ISNULL((SELECT created_at FROM cfr_pr_audit WHERE audit_status = 'Status 9' AND row_seq = 1 AND id = '306637'),(SELECT created_at FROM cfr_pr_audit WHERE audit_status = 'Status 10' AND row_seq = 1 AND id = '306637')) AS approved_at,
(SELECT created_at FROM cfr_pr_audit WHERE audit_status = 'Status 11' AND row_seq = 1 AND id = '306637') AS po_created_at
FROM cfr_pr_audit
以上查询适用于一个特定的 ID(我选择的那个 - 363114)。
我怎样才能使它适用于所有 ID?有点像通过不同 ID 的循环。
我尝试了以下选项:
选项 1:
SELECT DISTINCT
id AS purchase_request,
MIN(created_at) OVER (PARTITION BY id) AS created_at
FROM cfr_pr_audit
分区依据是最合乎逻辑的方法(我通常使用的方法),但是我被困在我试图获得的第三个值
(SELECT created_by FROM cfr_pr_audit WHERE created_at = (SELECT MIN(created_at) FROM cfr_pr_audit WHERE id = '363114') AND id = '363114') AS created_by
因为我在这里找不到 PARTITION BY 的方法。其余行也是如此——MIN(created_at) 是我唯一可以按(第二个值)
划分的部分选项2:
我想过做一些类似循环的事情
DECLARE @i INT = 0
SELECT @count = MAX(id_seq) FROM cfr_pr_audit
WHILE @i <= @count
BEGIN
SET @i = @i + 1;
MIN(created_at) OVER (PARTITION BY purchase_request) AS created_at
END
但不确定这是否可行并创建一个统一的 table 以及这是否有效。
非常感谢任何提示。
您可以将条件聚合与 window 函数一起使用:
SELECT DISTINCT id AS purchase_request,
MIN(created_at) OVER (PARTITION BY id) AS created_at,
FIRST_VALUE(created_by) OVER (PARTITION BY id ORDER BY created_at) AS created_by,
MAX(CASE WHEN audit_status = 'Status 8' AND row_seq = 1 AND pr_status <> 'NO PLACED' THEN created_at END) OVER (PARTITION BY id) AS submitted_at,
MAX(CASE WHEN audit_status = 'Status 8' AND row_seq = 1 AND pr_status <> 'NO PLACED' THEN created_by END) OVER (PARTITION BY id) AS submitted_by,
ISNULL(MAX(CASE WHEN audit_status = 'Status 9' AND row_seq = 1 THEN created_at END) OVER (PARTITION BY id),
MAX(CASE WHEN audit_status = 'Status 10' AND row_seq = 1 THEN created_at END) OVER (PARTITION BY id)) AS approved_at,
MAX(CASE WHEN audit_status = 'Status 11' AND row_seq = 1 THEN created_at END) OVER (PARTITION BY id) AS po_created_at
FROM cfr_pr_audit