C# 如何把一个table的行填充到另一个table
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# 如何把一个table的行填充到另一个table相关的知识,希望对你有一定的参考价值。
你这个Table是个什么对象?DataTable 还是html中的Table,还是其他类型?如果是DataTable,你可以先将原DataTable Clone给新DataTable,那么它的结构就传递给新数据表了,然后按行遍历旧DataTable,内层循环按DataColumns遍历
代码如下:
DataTable dt2= dt1.Clone();
for(int i=0;i<dt1.Rows.count;i++)
DataRow dr = dt2.NewRow();
foreach(DataColumn dc in dt2.Columns)
dr[dc.ColumnName] = dt1.Rows[i][dc.ColumnName];
dt2.Rows.Add(dr);
参考技术A 简单的全部添加,前提是保证两个datatable的column结构一样,我这里就是随便写的:
//源datatable
DataTable dt = new DataTable();
//目标datatable
DataTable destable = new DataTable();
destable.Rows.Add(dt.Rows);
上面是全部添加,如果要对row进行筛选可以用查询表达式:
//源datatable
DataTable dt = new DataTable();
//目标datatable
DataTable destable = new DataTable();
var rows = from DataRow row in dt.Rows
where true//这里改为筛选条件
select row;
destable.Rows.Add(rows.Take(1));//数字1可以改为要添加的条数,不能超过rows的总数 参考技术B insert into table2
select ***** from table1
where *****
数据列要保持一致
SQL:如何限制第一个找到的行的连接?
【中文标题】SQL:如何限制第一个找到的行的连接?【英文标题】:SQL: how to limit a join on the first found row? 【发布时间】:2016-05-17 06:24:50 【问题描述】:如何在两个表之间进行连接,但仅限于满足连接条件的第一行?
在这个简单的示例中,我想为 table_A 中的每一行获取 table_B 中满足条件的第一行:
select table_A.id, table_A.name, table_B.city
from table_A join table_B
on table_A.id = table_B.id2
where ..
table_A (id, name)
1, John
2, Marc
table_B (id2, city)
1, New York
1, Toronto
2, Boston
The output would be:
1, John, New York
2, Marc, Boston
可能是 Oracle 提供了这样的功能(性能是一个问题)。
【问题讨论】:
select * from table_A join (select * feom table_B group by id2) b on table_A.id = b.id2 where .. 加入带有 row_number 的 subqery 并在加入条件中添加和 row_number=1 “第一”是什么意思?表格没有顺序。 【参考方案1】:这里的关键词是FIRST。您可以使用解析函数FIRST_VALUE
或聚合构造FIRST
。
对于FIRST
或LAST
,性能永远不会比等效的FIRST_VALUE
或LAST_VALUE
构造更差,而且通常更好,因为我们没有多余的窗口排序,因此执行成本更低:
select table_A.id, table_A.name, firstFromB.city
from table_A
join (
select table_B.id2, max(table_B.city) keep (dense_rank first order by table_B.city) city
from table_b
group by table_B.id2
) firstFromB on firstFromB.id2 = table_A.id
where 1=1 /* some conditions here */
;
由于 12c 引入了运算符 LATERAL
以及 CROSS/OUTER APPLY
连接,因此可以在 JOIN
子句的右侧使用相关子查询:
select table_A.id, table_A.name, firstFromB.city
from table_A
cross apply (
select max(table_B.city) keep (dense_rank first order by table_B.city) city
from table_b
where table_B.id2 = table_A.id
) firstFromB
where 1=1 /* some conditions here */
;
【讨论】:
【参考方案2】:如果您只想要单个值,可以使用标量子查询:
SELECT
id, name, (SELECT city FROM table_B WHERE id2 = table_A.id AND ROWNUM = 1) city
FROM
table_A
【讨论】:
这会对性能产生重大影响,为从 table_A 返回的每一行运行一个子查询。 这取决于 table_A.id 不同的值及其分布。搜索“标量子查询缓存”。在很多情况下,这是非常好的方法。 排序和子查询嵌套怎么样?您的情况在 11g 中不起作用【参考方案3】:查询:
SELECT a.id,
a.name,
b.city
FROM table_A a
INNER JOIN
( SELECT id2,
city
FROM (
SELECT id2,
city,
ROW_NUMBER() OVER ( PARTITION BY id2 ORDER BY NULL ) rn
FROM Table_B
)
WHERE rn = 1
) b
ON ( a.id = b.id2 )
--WHERE ...
输出:
ID NAME CITY
---------- ---- --------
1 John New York
2 Marc Boston
【讨论】:
【参考方案4】:select table_A.id, table_A.name,
FIRST_VALUE(table_B.city) IGNORE NULLS
OVER (PARTITION BY table_B.id2 ORDER BY table_B.city) AS "city"
from table_A join table_B
on table_A.id = table_B.id2
where ..
【讨论】:
【参考方案5】:在 Oracle12c 上,终于有了新的 cross/outer apply operator,它可以满足您的要求而无需任何解决方法。
以下示例在字典视图中查找名称以“SYS”开头的用户拥有的(可能)许多对象之一:
select *
from (
select USERNAME
from ALL_USERS
where USERNAME like 'SYS%'
) U
cross apply (
select OBJECT_NAME
from ALL_OBJECTS O
where O.OWNER = U.USERNAME
and ROWNUM = 1
)
在 Oracle 11g 和之前的版本中,您应该只使用通常基于第二个表的 ID 对第二个表进行全扫描以获得相同结果的变通方法,但为了测试目的,您可以启用 lateral operator(也适用于 12c无需启用新东西)并使用另一个
-- Enables some new features
alter session set events '22829 trace name context forever';
select *
from (
select USERNAME
from ALL_USERS
where USERNAME like 'SYS%'
) U,
lateral (
select OBJECT_NAME
from ALL_OBJECTS O
where O.OWNER = U.USERNAME
and ROWNUM = 1
);
【讨论】:
【参考方案6】:此解决方案使用整个表,就像在常规连接中一样,但仅限于第一行。我发布这个是因为对我来说其他解决方案还不够,因为它们只使用一个字段,或者它们对大表有性能问题。我不是 Oracle 专家,所以如果有人可以改进这一点,请这样做,我很乐意使用您的版本。
select *
from tableA A
cross apply (
select *
from (
select B.*,
ROW_NUMBER() OVER (
-- replace this by your own partition/order statement
partition by B.ITEM_ID order by B.DELIVERYDATE desc
) as ROW_NUM
from tableB B
where
A.ITEM_ID=B.ITEM_ID
)
where ROW_NUM=1
) B
【讨论】:
【参考方案7】:我用partition把id2隔开,然后只取r_num = 1。
SELECT A.ID, A.NAME, B.CITY
FROM TABLE_A A,
(SELECT ID2, CITY,
ROW_NUMBER() OVER (PARTITION BY ID2 ORDER BY ID2) AS R_NUM
FROM TABLE_B) B
WHERE A.ID = B.ID2
AND R_NUM = 1;
【讨论】:
这似乎是迄今为止最紧凑的解决方案。使用 cross apply 和你知道的 this 之间有什么性能差异吗?以上是关于C# 如何把一个table的行填充到另一个table的主要内容,如果未能解决你的问题,请参考以下文章
如何避免使用角度材料从角度 2 中的 mat-table 传输相同的行