请问如何获得GridView选中行的每一列的信息?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了请问如何获得GridView选中行的每一列的信息?相关的知识,希望对你有一定的参考价值。
参考技术A 1、先在GridView上绑定datakeysName把ID绑上去
2、
加个选择列
在GridView的SelectedIndexChanging时间中获得选择行的ID
方法是:
int.Parse(this.GridView1.DataKey.[e.RowIndex].Value.ToString());
3、
然后根据ID查出来,一个一个赋值到文本框中
检索行的每一列的最后一个已知值
【中文标题】检索行的每一列的最后一个已知值【英文标题】:Retrieve last known value for each column of a row 【发布时间】:2013-12-13 07:37:22 【问题描述】:不确定问这个问题的正确词,所以我会分解它。
我有一张如下表:
date_time | a | b | c
最后 4 行:
15/10/2013 11:45:00 | null | 'timtim' | 'fred'
15/10/2013 13:00:00 | 'tune' | 'reco' | null
16/10/2013 12:00:00 | 'abc' | null | null
16/10/2013 13:00:00 | null | 'died' | null
我将如何获取最后一条记录,但其值忽略空值,而是从上一条记录中获取值。
在我提供的示例中,返回的行将是
16/10/2013 13:00:00 | 'abc' | 'died' | 'fred'
如您所见,如果一列的值为空,那么它将转到具有该列值并使用该值的最后一条记录。
这应该是可能的,我只是想不通。到目前为止,我只提出了:
select
last_value(a) over w a
from test
WINDOW w AS (
partition by a
ORDER BY ts asc
range between current row and unbounded following
);
但这仅适用于单个列...
【问题讨论】:
最后一个数据是插入的顺序还是最大日期时间? 最后一条数据是插入的顺序 表格中没有自然顺序。表是没有顺序的集合。只要您不在某处存储该信息,"last data is the order that was inserted"
就不会被定义。 CTID不可靠。它可以通过任何更新或恢复随时更改。
【参考方案1】:
行的顺序
需要明确定义“最后一行”和排序顺序。集合(或表格)中没有自然顺序。我假设ORDER BY ts
,其中 ts 是时间戳列。
像@Jorge pointed out in his comment:如果ts
不是UNIQUE
,则需要为排序顺序定义决胜局以使其明确(向ORDER BY
添加更多项目)。主键将是最终的解决方案。
使用窗口函数的一般解决方案
要获得每一行行的结果:
SELECT ts
, max(a) OVER (PARTITION BY grp_a) AS a
, max(b) OVER (PARTITION BY grp_b) AS b
, max(c) OVER (PARTITION BY grp_c) AS c
FROM (
SELECT *
, count(a) OVER (ORDER BY ts) AS grp_a
, count(b) OVER (ORDER BY ts) AS grp_b
, count(c) OVER (ORDER BY ts) AS grp_c
FROM t
) sub;
如何?
聚合函数count()
在计数时会忽略 NULL 值。用作聚合窗口函数,它根据default window definition, which is RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
计算列的运行计数。 NULL 值不会增加计数,因此这些行与最后一个非 null 值属于同一对等组。
在第二个窗口函数中,使用max()
或 min() 可以轻松提取每组唯一的非空值。
就在最后一行
WITH cte AS (
SELECT *
, count(a) OVER w AS grp_a
, count(b) OVER w AS grp_b
, count(c) OVER w AS grp_c
FROM t
WINDOW w AS (ORDER BY ts)
)
SELECT ts
, max(a) OVER (PARTITION BY grp_a) AS a
, max(b) OVER (PARTITION BY grp_b) AS b
, max(c) OVER (PARTITION BY grp_c) AS c
FROM cte
ORDER BY ts DESC
LIMIT 1;
最后一行的简单替代方案
SELECT ts
,COALESCE(a, (SELECT a FROM t WHERE a IS NOT NULL ORDER BY ts DESC LIMIT 1)) AS a
,COALESCE(b, (SELECT b FROM t WHERE b IS NOT NULL ORDER BY ts DESC LIMIT 1)) AS b
,COALESCE(c, (SELECT c FROM t WHERE c IS NOT NULL ORDER BY ts DESC LIMIT 1)) AS c
FROM t
ORDER BY ts DESC
LIMIT 1;
或者:
SELECT (SELECT ts FROM t ORDER BY ts DESC LIMIT 1) AS ts
,(SELECT a FROM t WHERE a IS NOT NULL ORDER BY ts DESC LIMIT 1) AS a
,(SELECT b FROM t WHERE b IS NOT NULL ORDER BY ts DESC LIMIT 1) AS b
,(SELECT c FROM t WHERE c IS NOT NULL ORDER BY ts DESC LIMIT 1) AS c
db小提琴here旧sqlfiddle
性能
虽然这应该很快,但如果性能是您的首要要求,请考虑使用 plpgsql 函数。从最后一行开始并循环降序,直到所需的每一列都有一个非空值。沿着这些思路:
GROUP BY and aggregate sequential numeric values【讨论】:
您的答案无法正常工作。看到这个测试:sqlfiddle.com/#!12/4ba24/1 @JorgeCampos:当然可以。您的示例仅表明如果 ts 不是UNIQUE
,则仅按时间戳列 ts
的排序是未明确定义。在这方面的问题是不清楚的。就像您认为的那样,RDBMS 的表中没有自然顺序。通过 CTID 订购并非不可靠。顺便说一句,我添加了没有窗口功能的简单版本。
我想你误会了我,我喜欢你的回答,比我自己的要优雅得多。我之所以指出这一点,是因为与 OP 关于 cmets 的讨论。我只是指出,所以你可以修复。如果您解决此问题,我希望看到 OP 取消标记我的答案并标记您的答案。正如我所说,我的答案是一个丑陋的解决方案。 :)
@JorgeCampos:嗯,谢谢你的提琴。为此,我添加了一段来澄清排序顺序的问题。【参考方案2】:
在这里,我创建了一个将列收集到数组中的聚合函数。然后只需删除 NULL 并从每个数组中选择最后一个元素。
样本数据
CREATE TABLE T (
date_time timestamp,
a text,
b text,
c text
);
INSERT INTO T VALUES ('2013-10-15 11:45:00', NULL, 'timtim', 'fred'),
('2013-10-15 13:00:00', 'tune', 'reco', NULL ),
('2013-10-16 12:00:00', 'abc', NULL, NULL ),
('2013-10-16 13:00:00', NULL, 'died', NULL );
解决方案
CREATE AGGREGATE array_accum (anyelement)
(
sfunc = array_append,
stype = anyarray,
initcond = ''
);
WITH latest_nonull AS (
SELECT MAX(date_time) As MaxDateTime,
array_remove(array_accum(a), NULL) AS A,
array_remove(array_accum(b), NULL) AS B,
array_remove(array_accum(c), NULL) AS C
FROM T
ORDER BY date_time
)
SELECT MaxDateTime, A[array_upper(A, 1)], B[array_upper(B,1)], C[array_upper(C,1)]
FROM latest_nonull;
结果
maxdatetime | a | b | c
---------------------+-----+------+------
2013-10-16 13:00:00 | abc | died | fred
(1 row)
【讨论】:
如果最后一个注册表的日期是 15/10/2013 11:45:00 会起作用吗? 抱歉,我是 postgres 新手,当我尝试创建聚合时,我收到错误 ERROR: function array_prepend(anyarray, anyelement) does not exist SQL state: 42883 @JorgeCampos 不,我没有看到问题下的 cmets。我会修复它。这假设最后一次插入是最新的时间戳。 @cghrmauritius 这是一个错字,如果你现在查看代码,它有array_append
而不是 array_prepend
)
ok 似乎到了某个地方,我已经设法创建了聚合谢谢,但是 with iss throwing ERROR: function array_remove(text[], unknown) does not exist SQL state: 42883 提示:没有函数匹配给定的名称和参数类型。您可能需要添加显式类型转换。字符:72【参考方案3】:
这应该可行,但请记住这是一个丑陋的解决方案
select * from
(select dt from
(select rank() over (order by ctid desc) idx, dt
from sometable ) cx
where idx = 1) dtz,
(
select a from
(select rank() over (order by ctid desc) idx, a
from sometable where a is not null ) ax
where idx = 1) az,
(
select b from
(select rank() over (order by ctid desc) idx, b
from sometable where b is not null ) bx
where idx = 1) bz,
(
select c from
(select rank() over (order by ctid desc) idx, c
from sometable where c is not null ) cx
where idx = 1) cz
在 fiddle 看到它:http://sqlfiddle.com/#!15/d5940/40
结果是
DT A B C
October, 16 2013 00:00:00+0000 abc died fred
【讨论】:
这建立在不存在的“自然秩序”之上。此外,您根本不需要这种方法的窗口函数。考虑一下我的回答中的“简单替代方案”。以上是关于请问如何获得GridView选中行的每一列的信息?的主要内容,如果未能解决你的问题,请参考以下文章