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

如何从DICTIONARY表获取首个DATE和NUM格式的列名?

获取表中首个NUM类型和DATE格式列的正确方法

你之前用max()函数得到的是列名字母顺序最大的结果,而非变量在表中的实际顺序,要解决这个问题,必须利用DICTIONARY.COLUMNS里的VARNUM属性——它记录了变量在表中的位置序号,按这个排序就能拿到真实的变量顺序。

下面提供两种可行的实现方式:

方法1:PROC SQL窗口函数实现

通过窗口函数ROW_NUMBER()按库名、表名分组,对变量按VARNUM升序排序,筛选出每个表中符合条件的第一条记录:

proc sql;
create table want as
select 
    UPCASE(libname) as mylib,
    UPCASE(memname) as mytable,
    max(case when rn_num = min_num_rn then first_att_num end) as first_att_num,
    max(case when rn_num = min_date_rn then first_att_date end) as first_att_date
from (
    select 
        libname,
        memname,
        case when type='num' and xtype in ('','decimal') then upcase(name) end as first_att_num,
        case when substr(format,1,4)='DATE' and xtype in ('date','num') then upcase(name) end as first_att_date,
        row_number() over(partition by libname, memname order by varnum) as rn_num,
        /* 记录每个表中首个NUM列的行号 */
        min(case when type='num' and xtype in ('','decimal') then row_number() over(partition by libname, memname order by varnum) end) 
            over(partition by libname, memname) as min_num_rn,
        /* 记录每个表中首个DATE列的行号 */
        min(case when substr(format,1,4)='DATE' and xtype in ('date','num') then row_number() over(partition by libname, memname order by varnum) end) 
            over(partition by libname, memname) as min_date_rn
    from DICTIONARY.COLUMNS
    where (upcase(libname), upcase(memname)) in (select upcase(libname), upcase(memname) from have)
)
group by libname, memname;
quit;

方法2:DATA步实现(逻辑更直观)

先把字典表的变量按库、表、VARNUM排序,再按表分组,逐个检查变量,记录第一个符合条件的列名:

/* 先整理需要查询的表列表 */
proc sort data=have out=have_sorted;
    by libname memname;
run;

/* 提取目标表的变量信息,按实际顺序排序 */
proc sql;
create table cols_sorted as
select 
    UPCASE(t1.libname) as mylib,
    UPCASE(t1.memname) as mytable,
    upcase(t1.name) as colname,
    t1.type,
    t1.xtype,
    t1.format
from DICTIONARY.COLUMNS t1
inner join have_sorted t2
    on upcase(t2.libname) = upcase(t1.libname)
    and upcase(t2.memname) = upcase(t1.memname)
order by mylib, mytable, t1.varnum;
quit;

/* 遍历每个表,提取首个符合条件的列 */
data want;
    set cols_sorted;
    by mylib mytable;
    /* 每个表开始时清空临时变量 */
    if first.mytable then do;
        first_att_num = '';
        first_att_date = '';
    end;
    /* 找到第一个NUM类型列就记录 */
    if first_att_num = '' and type='num' and xtype in ('','decimal') then
        first_att_num = colname;
    /* 找到第一个DATE格式列就记录 */
    if first_att_date = '' and substr(format,1,4)='DATE' and xtype in ('date','num') then
        first_att_date = colname;
    /* 每个表最后一行输出结果 */
    if last.mytable then output;
    keep mylib mytable first_att_num first_att_date;
run;

核心说明

  • VARNUM是关键:它决定了变量在原表中的顺序,这是你之前代码缺失的逻辑。
  • 原代码用max()是按列名的字母顺序取值,和变量实际位置无关,所以结果不符合预期。
  • DATA步的写法逻辑更清晰,适合调试;PROC SQL窗口函数则更简洁,处理大数据量时效率更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 16:34:49