sql server—如何选择第一行中的值是列名的sql数据集?

2wnc66cl  于 2021-07-24  发布在  Java
关注(0)|答案(4)|浏览(371)

我有这样的数据:

ID RowType Col_1       Col_2     Col_3       ... Col_n
1  HDR     FirstName   LastName  Birthdate
2  DTL     Steve       Bramblet  1989-01-01
3  DTL     Bob         Marley    1967-03-12
4  DTL     Mickey      Mouse     1921-04-25

我想返回一个如下所示的表或数据集:

ID    FirstName    LastName    Birthdate
2     Steve        Bramblet    1989-01-01
3     Bob          Marley      1967-03-12
4     Mickey       Mouse       1921-04-25

其中n=255(因此有255列字段的限制)

编辑:hdr行中的数据是任意的,所以我只使用firstname,lastname,birthdate作为示例。这就是为什么我认为它需要是动态sql,因为我想要结束的列名将根据hdr行中的值而改变。谢谢

如果有一个纯粹的sql解决方案,那就是我想要的。它将进入一个etl进程(ssis),因此如果其他所有任务都失败,我可以使用脚本任务。
即使我可以返回一行,这也是一个解决方案。我在想可能有一个动态sql解决方案可以解决这样的问题:

select Col_1 as FirstName, Col_2 as LastName, Col_3 as Birthdate
qmb5sa22

qmb5sa221#

不确定您的第一个数据段是否已经在oracle表中,但它在csv文件中,那么您可以选择在加载过程中跳过标题。
如果数据已经在表中,那么您可以使用 UNION 为了得到想要的结果

Select * from table name where rowtype=‘HRD’
union
select * from table name where rowtype=‘DTL’

如果您需要名字等作为列标题,那么您不需要做任何事情。根据您的要求设计目标表列。

3vpjnl9f

3vpjnl9f2#

很抱歉,发布了一个答案,但我完全误解了您在源表中将所需的列标题作为数据。
一个简单的解决方案(尽管它需要更多的io)是将表数据转储到一个没有头的平面文件中,然后将其读回,但这次告诉ssis第一行有头,并忽略 RowType 列。在将数据写入中间文件之前,请确保对其进行了正确排序!
要转储到没有标题的文件,必须设置 ColumnNamesInFirstDataRowfalse . 在“属性”窗口中设置,而不是通过编辑连接。此线程中的详细信息
如果你有大量的数据,这显然是非常低效的。

unguejic

unguejic3#

使用以下命令尝试 row_number . 这是演示。

with cte as
(
  select
    *,
    row_number() over (order by id) as rn
  from myTable
)

select
    ID,
    Col_1 as FirstName,
    Col_2 as LastName,
    Col_3 as Birthdate
from cte
where rn > 1

输出:

| id  | firstname | lastname | birthdate  |
| --- | --------- | -------- | ---------- |
| 2   | Steve     | Bramblet | 1989-01-01 |
| 3   | Bob       | Marley   | 1967-03-12 |
| 4   | Mickey    | Mouse    | 1921-04-25 |
i7uaboj4

i7uaboj44#

哦,好吧。有一种纯ssis方法,假设源是sql表。在这里,相当粗略。
创建类型为的变量ocolset Object ,和255个类型的变量 String 名字是scolname\u 1,scolname\u 2。。。scolnameÿ255。
创建一个sql任务 select top(1) Col_1, Col_2, ... Col_255 from Src where RowType = 'HDR' ,将任务属性resultset=full result set,在“结果集”选项卡上-将“结果名称”设置为0,将“变量名称”设置为 oColSet .
添加foreach循环枚举器,将其设置为 ForEach ADO Enumerator ,ado对象源变量-设置为 oColSet ,枚举模式=第一个表中的行。然后,在variable mappings选项卡上,定义如下示例( Variable - Index )-scolname\u 1-0,scolname\u 2-1。。。scolnameÿ255-254。
创建类型为的变量ssqlquery String 变量表达式

"SELECT Col_1 AS ["+@[User::sColName_1]+"], 
    Col_2 AS ["+@[User::sColName_2]+"], 
    ...
    Col_255 AS ["+@[User::sColName_255]+"]
 FROM Src WHERE RowType='DTL'"

在foreach循环中-添加数据流,在oledb源代码中-将数据访问模式设置为sql命令from variable并提供变量名 User::sSQLQuery . 在数据流本身上-设置delayvalidation=true。
此设计的主要思想是检索所有列名并将其存储在temp变量中(步骤2)。然后第3步进行解析并将所有结果放入相应的变量中,第1列(第0列)放入scolname\u 1等。第4步将sql命令定义为表达式,每次读取变量时都会对其进行计算。最后,在foreach循环(解析完成的地方)中执行数据流。
ssis的限制—数据类型和列名在运行时应与设计时相同。如果您需要进一步将数据集存储到sql中,请告诉我,这样我就可以调整建议的解决方案。

相关问题