You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SAS EG中高效获取数据表的最新数据

获取数据表最新数据的优化方案

问题背景

我有一张不定期更新的数据表,需要始终从中获取最新数据,可通过列PERIODAG_D(时间戳变量)是否接近当前日期判断数据是否为最新。

当前繁琐的实现方式

我当前通过outobs=1仅获取一条观测,并按PER_DAG_I(数值型日期变量)降序排序来拿到最新日期,再存入宏变量用于后续筛选:

步骤1:获取最新日期记录

PROC SQL OUTOBS=1;
   CREATE TABLE DESC_SORT AS 
   SELECT DISTINCT t3.PER_DAG_I, 
          t3.PERIODAG_D
      FROM COREPLNZ.KXYZ1000FCT t1
           LEFT JOIN COREPLNZ.KXYZ0090_SKEMA_JUNK t2 ON (t1.SKEMA_XYZ_JUNK_I = t2.SKEMA_XYZ_JUNK_I)
           LEFT JOIN COREPLNZ.TXYZ0200_KILDEFACT_DIM t4 ON (t1.KILDEFACT_I = t4.KILDEFACT_I)
           LEFT JOIN COREPLNZ.TKON0010PER_DAG_DIM t3 ON (t1.OPGOR_DAG_I = t3.PER_DAG_I)
      WHERE t4.KILDEFACT_NAVN = 'TLIK6000_RESTLOEBETID_FCT' AND t2.SKEMA_KODE = 'C 73.00'
      ORDER BY t3.PER_DAG_I DESC;
QUIT;

步骤2:将日期转换为宏变量

PROC SQL;
   CREATE TABLE DESC_SORT_FORMAT AS 
   SELECT t1.PERIODAG_D as str_perdag_Desc_sort, 
          t1.PERIODAG_D AS str_timestamp_Desc_sort,
          ("'"!!put(t1.PERIODAG_D,datetime22.3)!!"'dt") as str_SAStimestamp_Desc_sort
      FROM DESC_SORT t1;
QUIT;

PROC SQL NOPRINT;
SELECT DISTINCT 
          str_perdag_Desc_sort,
          str_timestamp_Desc_sort,
          str_SAStimestamp_Desc_sort
INTO      :str_perdag_Desc_sort,
          :str_timestamp_Desc_sort,
          :str_SAStimestamp_Desc_sort
FROM DESC_SORT_FORMAT;

步骤3:使用宏变量筛选最新数据

PROC SQL;
   CREATE TABLE WORK.QUERY_FOR_TXYZ1000FCT_000F(label="WORK.QUERY_FOR_TXYZ1000FCT_000F") AS 
   SELECT t2.PERIODAG_D AS OpgoerelseDato, 
          t6.PERIODAG_D AS AfviklingDato, 
          t1.KILDEFACT_Key_I, 
          t3.X_ORDINATE, 
          t3.Y_ORDINATE, 
          t3.Z_ORDINATE, 
          t4.SKEMA_KODE, 
          t4.SKEMA_NAVN, 
          t5.KILDEFACT_NAVN, 
          t7.KUNDE_SCD_I, 
          t7.KONTO_SCD_I, 
          t2.PER_DAG_I
      FROM COREPLNZ.KXYZ1000FCT t1
           LEFT JOIN COREPLNZ.TKON0010PER_DAG_DIM t2 ON (t1.OPGOR_DAG_I = t2.PER_DAG_I)
           LEFT JOIN COREPLNZ.TKON0010PER_DAG_DIM t6 ON (t1.AFVIKL_DAG_I = t6.PER_DAG_I)
           LEFT JOIN COREPLNZ.KXYZ0090_SKEMA_JUNK t3 ON (t1.SKEMA_XYZ_JUNK_I = t3.SKEMA_XYZ_JUNK_I)
           LEFT JOIN COREPLNZ.TXYZ0100_SKEMA_DIM t4 ON (t1.SKEMA_I = t4.SKEMA_I)
           LEFT JOIN COREPLNZ.TXYZ0200_KILDEFACT_DIM t5 ON (t1.KILDEFACT_I = t5.KILDEFACT_I)
           LEFT JOIN COREPLNZ.KLIK6000_RESTLOEBETID_FCT t7 ON (t1.KILDEFACT_Key_I = t7.RESTLOEBETID_FCT_I)
      WHERE t5.KILDEFACT_NAVN = 'TLIK6000_RESTLOEBETID_FCT' AND t4.SKEMA_KODE = 'C 73.00' AND t2.PERIODAG_D = 
           &str_SAStimestamp_Desc_sort
      ORDER BY t2.PER_DAG_I DESC;
QUIT;

这种方法步骤繁琐、效率低,以下是几种优化思路:

优化方案

1. 直接在SQL子查询中获取最新日期,无需中间表和宏变量

直接在主查询的WHERE子句中嵌入子查询,获取符合条件的最大PERIODAG_D,一步完成筛选:

PROC SQL;
   CREATE TABLE WORK.QUERY_FOR_TXYZ1000FCT_000F(label="WORK.QUERY_FOR_TXYZ1000FCT_000F") AS 
   SELECT t2.PERIODAG_D AS OpgoerelseDato, 
          t6.PERIODAG_D AS AfviklingDato, 
          t1.KILDEFACT_Key_I, 
          t3.X_ORDINATE, 
          t3.Y_ORDINATE, 
          t3.Z_ORDINATE, 
          t4.SKEMA_KODE, 
          t4.SKEMA_NAVN, 
          t5.KILDEFACT_NAVN, 
          t7.KUNDE_SCD_I, 
          t7.KONTO_SCD_I, 
          t2.PER_DAG_I
      FROM COREPLNZ.KXYZ1000FCT t1
           LEFT JOIN COREPLNZ.TKON0010PER_DAG_DIM t2 ON (t1.OPGOR_DAG_I = t2.PER_DAG_I)
           LEFT JOIN COREPLNZ.TKON0010PER_DAG_DIM t6 ON (t1.AFVIKL_DAG_I = t6.PER_DAG_I)
           LEFT JOIN COREPLNZ.KXYZ0090_SKEMA_JUNK t3 ON (t1.SKEMA_XYZ_JUNK_I = t3.SKEMA_XYZ_JUNK_I)
           LEFT JOIN COREPLNZ.TXYZ0100_SKEMA_DIM t4 ON (t1.SKEMA_I = t4.SKEMA_I)
           LEFT JOIN COREPLNZ.TXYZ0200_KILDEFACT_DIM t5 ON (t1.KILDEFACT_I = t5.KILDEFACT_I)
           LEFT JOIN COREPLNZ.KLIK6000_RESTLOEBETID_FCT t7 ON (t1.KILDEFACT_Key_I = t7.RESTLOEBETID_FCT_I)
      WHERE t5.KILDEFACT_NAVN = 'TLIK6000_RESTLOEBETID_FCT' 
        AND t4.SKEMA_KODE = 'C 73.00' 
        AND t2.PERIODAG_D = (
            SELECT MAX(t3.PERIODAG_D)
            FROM COREPLNZ.KXYZ1000FCT t1
                 LEFT JOIN COREPLNZ.KXYZ0090_SKEMA_JUNK t2 ON (t1.SKEMA_XYZ_JUNK_I = t2.SKEMA_XYZ_JUNK_I)
                 LEFT JOIN COREPLNZ.TXYZ0200_KILDEFACT_DIM t4 ON (t1.KILDEFACT_I = t4.KILDEFACT_I)
                 LEFT JOIN COREPLNZ.TKON0010PER_DAG_DIM t3 ON (t1.OPGOR_DAG_I = t3.PER_DAG_I)
            WHERE t4.KILDEFACT_NAVN = 'TLIK6000_RESTLOEBETID_FCT' AND t2.SKEMA_KODE = 'C 73.00'
          )
      ORDER BY t2.PER_DAG_I DESC;
QUIT;

2. 使用PROC SORT + 条件筛选直接获取最新批次数据

如果数据量较大,PROC SORT的效率可能优于SQL子查询。先筛选关联数据,再按日期降序排序,最后提取最新日期的所有记录:

/* 关联所有表并筛选基础条件 */
PROC SQL;
   CREATE TABLE WORK.JOINED_DATA AS
   SELECT t2.PERIODAG_D AS OpgoerelseDato, 
          t6.PERIODAG_D AS AfviklingDato, 
          t1.KILDEFACT_Key_I, 
          t3.X_ORDINATE, 
          t3.Y_ORDINATE, 
          t3.Z_ORDINATE, 
          t4.SKEMA_KODE, 
          t4.SKEMA_NAVN, 
          t5.KILDEFACT_NAVN, 
          t7.KUNDE_SCD_I, 
          t7.KONTO_SCD_I, 
          t2.PER_DAG_I
   FROM COREPLNZ.KXYZ1000FCT t1
        LEFT JOIN COREPLNZ.TKON0010PER_DAG_DIM t2 ON (t1.OPGOR_DAG_I = t2.PER_DAG_I)
        LEFT JOIN COREPLNZ.TKON0010PER_DAG_DIM t6 ON (t1.AFVIKL_DAG_I = t6.PER_DAG_I)
        LEFT JOIN COREPLNZ.KXYZ0090_SKEMA_JUNK t3 ON (t1.SKEMA_XYZ_JUNK_I = t3.SKEMA_XYZ_JUNK_I)
        LEFT JOIN COREPLNZ.TXYZ0100_SKEMA_DIM t4 ON (t1.SKEMA_I = t4.SKEMA_I)
        LEFT JOIN COREPLNZ.TXYZ0200_KILDEFACT_DIM t5 ON (t1.KILDEFACT_I = t5.KILDEFACT_I)
        LEFT JOIN COREPLNZ.KLIK6000_RESTLOEBETID_FCT t7 ON (t1.KILDEFACT_Key_I = t7.RESTLOEBETID_FCT_I)
   WHERE t5.KILDEFACT_NAVN = 'TLIK6000_RESTLOEBETID_FCT' AND t4.SKEMA_KODE = 'C 73.00';
QUIT;

/* 按日期降序排序 */
PROC SORT DATA=WORK.JOINED_DATA OUT=WORK.SORTED_DATA;
   BY DESCENDING OpgoerelseDato;
RUN;

/* 提取最新日期的所有数据 */
DATA WORK.QUERY_FOR_TXYZ1000FCT_000F;
   SET WORK.SORTED_DATA;
   IF _N_ = 1 THEN RETAIN LATEST_DATE;
   IF _N_ = 1 THEN LATEST_DATE = OpgoerelseDato;
   IF OpgoerelseDato = LATEST_DATE;
RUN;

3. 简化宏变量生成步骤,减少中间表

如果必须使用宏变量,可以直接在一个PROC SQL步骤中完成最新日期的获取和宏变量赋值,无需创建中间表:

PROC SQL NOPRINT;
   SELECT MAX(t3.PERIODAG_D) INTO :LATEST_TIMESTAMP
   FROM COREPLNZ.KXYZ1000FCT t1
        LEFT JOIN COREPLNZ.KXYZ0090_SKEMA_JUNK t2 ON (t1.SKEMA_XYZ_JUNK_I = t2.SKEMA_XYZ_JUNK_I)
        LEFT JOIN COREPLNZ.TXYZ0200_KILDEFACT_DIM t4 ON (t1.KILDEFACT_I = t4.KILDEFACT_I)
        LEFT JOIN COREPLNZ.TKON0010PER_DAG_DIM t3 ON (t1.OPGOR_DAG_I = t3.PER_DAG_I)
   WHERE t4.KILDEFACT_NAVN = 'TLIK6000_RESTLOEBETID_FCT' AND t2.SKEMA_KODE = 'C 73.00';
QUIT;

/* 使用宏变量筛选最新数据 */
PROC SQL;
   CREATE TABLE WORK.QUERY_FOR_TXYZ1000FCT_000F(label="WORK.QUERY_FOR_TXYZ1000FCT_000F") AS 
   SELECT t2.PERIODAG_D AS OpgoerelseDato, 
          t6.PERIODAG_D AS AfviklingDato, 
          t1.KILDEFACT_Key_I, 
          t3.X_ORDINATE, 
          t3.Y_ORDINATE, 
          t3.Z_ORDINATE, 
          t4.SKEMA_KODE, 
          t4.SKEMA_NAVN, 
          t5.KILDEFACT_NAVN, 
          t7.KUNDE_SCD_I, 
          t7.KONTO_SCD_I, 
          t2.PER_DAG_I
      FROM COREPLNZ.KXYZ1000FCT t1
           LEFT JOIN COREPLNZ.TKON0010PER_DAG_DIM t2 ON (t1.OPGOR_DAG_I = t2.PER_DAG_I)
           LEFT JOIN COREPLNZ.TKON0010PER_DAG_DIM t6 ON (t1.AFVIKL_DAG_I = t6.PER_DAG_I)
           LEFT JOIN COREPLNZ.KXYZ0090_SKEMA_JUNK t3 ON (t1.SKEMA_XYZ_JUNK_I = t3.SKEMA_XYZ_JUNK_I)
           LEFT JOIN COREPLNZ.TXYZ0100_SKEMA_DIM t4 ON (t1.SKEMA_I = t4.SKEMA_I)
           LEFT JOIN COREPLNZ.TXYZ0200_KILDEFACT_DIM t5 ON (t1.KILDEFACT_I = t5.KILDEFACT_I)
           LEFT JOIN COREPLNZ.KLIK6000_RESTLOEBETID_FCT t7 ON (t1.KILDEFACT_Key_I = t7.RESTLOEBETID_FCT_I)
      WHERE t5.KILDEFACT_NAVN = 'TLIK6000_RESTLOEBETID_FCT' AND t4.SKEMA_KODE = 'C 73.00' AND t2.PERIODAG_D = &LATEST_TIMESTAMP
      ORDER BY t2.PER_DAG_I DESC;
QUIT;

内容的提问来源于stack exchange,提问作者Christoffer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 17:35:24