Sql 在表中插入名称值(值1、值2、值3等);如何在单个表行中传输单个列的数据

Sql 在表中插入名称值(值1、值2、值3等);如何在单个表行中传输单个列的数据,sql,sas,Sql,Sas,大家好,我正在开发一个普通的系统,在这个系统中,我们可以添加许多带有数据集和字段的系统。我们可以在运行时添加每个系统的字段和数据,而无需更改数据库的结构 CREATE TABLE Type( ID int, Name varchar(255), PRIMARY KEY (ID) ); INSERT INTO Type VALUES (1, 'cust_obj_7'); INSERT INTO Type VALUES (2, 'cust_obj_8'); CRE

大家好,我正在开发一个普通的系统,在这个系统中,我们可以添加许多带有数据集和字段的系统。我们可以在运行时添加每个系统的字段和数据,而无需更改数据库的结构

CREATE TABLE Type(
    ID int,
    Name varchar(255),
    PRIMARY KEY (ID)
);

INSERT INTO Type VALUES (1, 'cust_obj_7');   

INSERT INTO Type VALUES (2, 'cust_obj_8');

CREATE TABLE Object(
    ID int,
    Name varchar(255),
    Description varchar(255),
    TypeID int,
    PRIMARY KEY (ID),
    FOREIGN KEY (TypeID ) REFERENCES Type(ID)
);

    INSERT INTO Object VALUES (1, 'First', 'First_desc', 1);

    INSERT INTO Object VALUES (2, 'Second', 'Second_desc', 1);

CREATE TABLE TypeFields(
    ID int,
    Name varchar(255),
    NameType varchar(255),
    TypeID int,
    PRIMARY KEY (ID),
    FOREIGN KEY (TypeID ) REFERENCES Type(ID)
);

 INSERT INTO TypeFields VALUES (1, 'First', 'str', 1);

 INSERT INTO TypeFields VALUES (2, 'Seond', 'str', 1);

 INSERT INTO TypeFields VALUES (3, 'Third', 'int', 1);

CREATE TABLE FieldsData(
    ID int,
    ObjectID int,
    FieldID int,
    FieldName varchar(255),
    TypeID int,
    value varchar(255),
    PRIMARY KEY (ID),
    FOREIGN KEY (TypeID ) REFERENCES Type(ID),
    FOREIGN KEY (ObjectID ) REFERENCES Object(ID),
    FOREIGN KEY (FieldID ) REFERENCES TypeFields(ID)
);

 INSERT INTO VALUES (1, 1, 1, 'First', 1, "a");
 INSERT INTO VALUES (2, 1, 2, 'Second', 1, "b");
 INSERT INTO VALUES (3, 1, 3, 'Third', 1, "120");
 INSERT INTO VALUES (4, 2, 1, 'First', 1, "c");
 INSERT INTO VALUES (5, 2, 2, 'Second', 1, "d");
 INSERT INTO VALUES (6, 2, 3, 'Third', 1, "130");

CREATE TABLE FinalTable(
        ObjID int,
        ObjName varchar(255),
        ObjDesc varchar(255),
        First varchar(255),
        Second varchar(255),
        Third int
    );
数据将如下所示

我想从这些表中创建一个数据集作为finaltable,如上所示。我可以使用键获取所有数据,但我遇到了从不同行的列将数据写入单行的问题。我被困在如何在sas base中使用sql实现这一点上。

首先,“我的自定义表”应该是源自“字段数据”的视图。“字段数据”有点用词不当,因为它包含字段的值。因此,在一个抽象中,这种区别对于理解您正在构建的框架非常重要

“我的自定义表”中的一行似乎用于投影TypeID=1。您不会显示其他TypeID值,但我认为它们适用于不同的自定义表

自定义表实际上应该是视图,否则每个对象在存储需求方面都是一个潜在的+1倍增

在示例图像中,“我的自定义表”的第二行的ObjID=2,但显示了对应于ObjID=2的“字段数据”中的值。我猜是打字错误

不在自定义表中呈现“对象类型”名称,因此我认为它只是类型目录。

你现在的设计还不是一个标准的形式。不确定为什么在“Fields data”中复制FieldName,您有一个FieldID,它引用了一个名为的记录。不确定为什么TypeID出现在“字段数据”中,因为TypeID本质上是“字段数据”所需投影的目录项选择器

这种设计会导致大量的革新,并且需要大量的时间来充实不同的值类型,如日期、值呈现格式、多值类型等

无论如何,将值数据作为对象类型投影到自定义表本质上是合并对象、类型字段和数据字段的联接的转置。SAS SQL没有透视运算符(如MS SQL Server中的透视运算符)。SQL中的“老派”支点方法涉及在分组上聚合case语句

有一些针对“任意”的设计,它简单地杀死了所有中间人,并拥有一个巨大的价值整体,包括20个ID字段、1000个数字字段、1000个字符字段和100个日期字段,每个“对象”都是针对它的用例SQL视图

**编辑-添加到下面**

添加了演示“老派”轴心的代码:

PROC SQL; 

CREATE TABLE Type(
    ID int,
    Name varchar(255)/*,
    PRIMARY KEY (ID)*/
);

INSERT INTO Type VALUES (1, 'cust_obj_7');   
INSERT INTO Type VALUES (2, 'cust_obj_8');

CREATE TABLE Object(
    ID int,
    Name varchar(255),
    Description varchar(255),
    TypeID int/*,
    PRIMARY KEY (ID),
    FOREIGN KEY (TypeID ) REFERENCES Type(ID);*/
);

    INSERT INTO Object VALUES (1, 'First', 'First_desc', 1);
    INSERT INTO Object VALUES (2, 'Second', 'Second_desc', 1);

CREATE TABLE TypeFields(
    ID int,
    Name varchar(255),
    NameType varchar(255),
    TypeID int/*,
    PRIMARY KEY (ID),
    FOREIGN KEY (TypeID ) REFERENCES Type(ID) */
);

 INSERT INTO TypeFields VALUES (1, 'First', 'str', 1);
 INSERT INTO TypeFields VALUES (2, 'Seond', 'str', 1);
 INSERT INTO TypeFields VALUES (3, 'Third', 'int', 1);

CREATE TABLE FieldsData(
    ID int,
    ObjectID int,
    FieldID int,
    FieldName varchar(255),
    TypeID int,
    value varchar(255)/*,
    PRIMARY KEY (ID),
    FOREIGN KEY (TypeID ) REFERENCES Type(ID),
    FOREIGN KEY (ObjectID ) REFERENCES Object(ID),
    FOREIGN KEY (FieldID ) REFERENCES TypeFields(ID)*/
);

 INSERT INTO FieldsData VALUES (1, 1, 1, 'First', 1, "a");
 INSERT INTO FieldsData  VALUES (2, 1, 2, 'Second', 1, "b");
 INSERT INTO FieldsData  VALUES (3, 1, 3, 'Third', 1, "120");
 INSERT INTO FieldsData  VALUES (4, 2, 1, 'First', 1, "c");
 INSERT INTO FieldsData  VALUES (5, 2, 2, 'Second', 1, "d");
 INSERT INTO FieldsData  VALUES (6, 2, 3, 'Third', 1, "130");

CREATE TABLE FinalTable(
        ObjID int PRIMARY KEY,
        ObjName varchar(255),
        ObjDesc varchar(255),
        First varchar(255),
        Second varchar(255),
        Third int
    );

create view example_type1_realized as
    select 
      FieldsData.ObjectID as ObjID
    , max(Object.Name) as ObjName
    , max(Object.Description) as ObjDesc
    , max(case when FieldID=1 then Value end) as First
    , max(case when FieldID=2 then Value end) as Second
    , max(case when FieldID=3 then input(Value,best12.) end) as Third
    from FieldsData 
    join Object 
      on FieldsData.ObjectID = Object.ID
    where TypeID = 1
    group by ObjID
    ;  
现在,对于每个TypeID,您将需要构造一个代码生成器来创建源代码墙纸。。。最大值(从TypeFields数据构造时的大小写)

这里有一个方法:

* Now a codegener macro that can produce the example realization: ;

%macro realize (TypeID=, out=);
  %local wallpaper;

  proc sql noprint;

    select cat
    (
      ', max(case when FieldID=', cats(ID), ' then '
      , case 
          when NameType='str' then 'Value'
          when NameType='int' then 'input(Value,12.)'
          else 'cats(Value) || " (' || NameType || ') unhandled"'
        end
      , ' end)'
      , ' as ', Name
    ) length=32000
    into :wallpaper separated by ' '
    from TypeFields
    where TypeID = &TypeID
    ;

%put NOTE: wallpaper=%SUPERQ(wallpaper);

    create &out as 
      select 
        FieldsData.ObjectID as ObjID
      , max(Object.Name) as ObjName
      , max(Object.Description) as ObjDesc
      &wallpaper
      from FieldsData 
      join Object 
        on FieldsData.ObjectID = Object.ID
      group by ObjID
      ;
  quit;
%mend;

options mprint;
%realize(TypeID=1, out=table type1_replicate)
您可以修改codegener,以便它将行插入out=中,而不是重新创建


您应该看到,您的系统是可行的,但要成为泛型需要大量的关注。每个字段类型可能会得到格式、信息、长度、日期处理、类型值超出范围的错误处理、字段序列等。

请将示例数据作为文本发布,以便人们可以使用它来重现问题。@Tom我已更新了代码。您的SQL语法对于
PROC SQL
无效。这就是问题所在吗?您是否询问如何读取关于应创建哪些字段的元数据,并使用这些元数据创建空数据集?使用数据集
字段数据中的字符串
将记录插入现有数据集中,converti在适当的情况下,将其从字符转换为数字?或者两者兼而有之?FieldName和TypeID只是为了帮助开发人员,因为他可以很容易地理解FinalTable中需要哪些字段取出图像或将其替换为与插入数据相匹配的字段。
* Now a codegener macro that can produce the example realization: ;

%macro realize (TypeID=, out=);
  %local wallpaper;

  proc sql noprint;

    select cat
    (
      ', max(case when FieldID=', cats(ID), ' then '
      , case 
          when NameType='str' then 'Value'
          when NameType='int' then 'input(Value,12.)'
          else 'cats(Value) || " (' || NameType || ') unhandled"'
        end
      , ' end)'
      , ' as ', Name
    ) length=32000
    into :wallpaper separated by ' '
    from TypeFields
    where TypeID = &TypeID
    ;

%put NOTE: wallpaper=%SUPERQ(wallpaper);

    create &out as 
      select 
        FieldsData.ObjectID as ObjID
      , max(Object.Name) as ObjName
      , max(Object.Description) as ObjDesc
      &wallpaper
      from FieldsData 
      join Object 
        on FieldsData.ObjectID = Object.ID
      group by ObjID
      ;
  quit;
%mend;

options mprint;
%realize(TypeID=1, out=table type1_replicate)