给定一个包含如下记录的 MS SQL EXPRESS 2008 R2 表
ArchiveId ScheduleId Data
391063 62 <Data>....</Data>
391064 62 <Data>....</Data>
391065 63 <Data>....</Data>
Data Field 中的 XML 结构如下
<Data>
<Value>1.0</Value>
<Value>2.0</Value>
<Value>3.0</Value>
<Value>4.0</Value>
</Data>
使用以下捕获进行选择的最快方法是什么
Value节点切碎成列<Value> <Data> 中的节点节点,它们总是数字理想情况下,我正在寻找格式的数据;
ArchiveId ScheduleId Value1 Value2 etc
391063 62 1.0 2.0
391064 62 1.1 2.1
我试过用
select
ArchiveId,
ScheduleId ,
v.value('(Value/text())[1]', 'float') as value1 ,
v.value('(Value/text())[2]', 'float') as value2 ,
v.value('(Value/text())[3]', 'float') as value3 ,
v.value('(Value/text())[4]', 'float') as value4
from
Archives
cross apply [data].nodes('//Data') x(v)
where
ScheduleId = 2499
和直接的 .values() 和 .queries()
select
ArchiveId,
ScheduleId,
Data.value('(/Data/Value/text())[1]', 'float') as value1,
Data.value('(/Data/Value/text())[2]', 'float') as value2,
Data.value('(/Data/Value/text())[3]', 'float') as value3,
Data.value('(/Data/Value/text())[4]', 'float') as value4
from
Archives
where
ScheduleId = 2499
order by
ArchiveId asc
两者都有效,但在大型数据集上确实很慢,我想知道是否有更快的方法在非常大量的行上执行此类操作。我意识到,无论做什么都需要一段时间,但这样做时我最好的选择是什么。
这里的例子很多,但它们都有更复杂或动态的数据结构,或者有某种基于 xml 内容本身的复杂选择要求。
我拥有的数据始终是相同的结构(一个数据节点和 x 值节点)并且选择标准根本不在 xml 中。
我只是在寻找最简单的方法来拉回大量记录,同时将 xml 扁平化为列。
编辑:本质上,我们将图形数据存储在 xml 中,以便稍后绘制折线图。重要的是,虽然相同 ScheduleId 的元素数量始终相同,但不同的 ScheduleId 将具有不同数量的值元素。
最佳答案
如果您可以将字段添加到 Archives 表,则可以创建持久的计算字段作为 XML 数据的函数。因此,例如,您创建一个字段 value1 并将其设置为等于 Data.value('(/Data/Value/text())[1]', 'float') 然后在列上设置持久标志。这样,当记录被添加或更新时,它将被解析一次,然后它有自己的数据字段,您可以选择输出。
虽然不能直接使用 XML 方法,但由于您必须使用 udf,因此在实践中有点笨拙。但它看起来像这样:
GO
create table TempArchive
(
ArchiveId integer not null,
ScheduleId integer not null,
[Data] xml not null,
CONSTRAINT PK_Archive
PRIMARY KEY CLUSTERED (ArchiveId)
WITH (IGNORE_DUP_KEY = OFF)
)
GO
create function udf_getdatacolumn
(
@data xml,
@index as int
) RETURNS float
with schemabinding
as
begin
return @data.value('(/Data/Value/text())[sql:variable("@index")][1]', 'float')
end
GO
alter table TempArchive add value1 as (dbo.udf_getdatacolumn(data, 1)) persisted
alter table TempArchive add value2 as (dbo.udf_getdatacolumn(data, 2)) persisted
alter table TempArchive add value3 as (dbo.udf_getdatacolumn(data, 3)) persisted
alter table TempArchive add value4 as (dbo.udf_getdatacolumn(data, 4)) persisted
GO
insert into TempArchive values (1, 2, '<Data>
<Value>1.0</Value>
<Value>2.0</Value>
<Value>3.0</Value>
<Value>4.0</Value>
</Data>')
GO
select ArchiveId, ScheduleId, Value1, Value2, Value3, Value4
from TempArchive
GO
返回:
ArchiveId ScheduleId Value1 Value2 Value3 Value4
----------- ----------- ---------- ---------- ---------- ----------
1 2 1 2 3 4
(1 row(s) affected)
请记住,对于大量数据,首次添加这些计算列时会花费很长时间。我建议在投入生产之前对其进行测试。它还会增加表格的大小。
关于sql-server - 在具有切碎/扁平 xml 字段的大表上更快地选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30916859/
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr
我正在使用Rails3.1并在一个论坛上工作。我有一个名为Topic的模型,每个模型都有许多Post。当用户创建新主题时,他们也应该创建第一个Post。但是,我不确定如何以相同的形式执行此操作。这是我的代码:classTopic:destroyaccepts_nested_attributes_for:postsvalidates_presence_of:titleendclassPost...但这似乎不起作用。有什么想法吗?谢谢! 最佳答案 @Pablo的回答似乎有你需要的一切。但更具体地说...首先改变你View中的这一行对此#
目录第1题连续问题分析:解法:第2题分组问题分析:解法:第3题间隔连续问题分析:解法:第4题打折日期交叉问题分析:解法:第5题同时在线问题分析:解法:第1题连续问题如下数据为蚂蚁森林中用户领取的减少碳排放量iddtlowcarbon10012021-12-1212310022021-12-124510012021-12-134310012021-12-134510012021-12-132310022021-12-144510012021-12-1423010022021-12-154510012021-12-1523.......找出连续3天及以上减少碳排放量在100以上的用户分析:遇到这类
我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时
我从用户Hirolau那里找到了这段代码:defsum_to_n?(a,n)a.combination(2).find{|x,y|x+y==n}enda=[1,2,3,4,5]sum_to_n?(a,9)#=>[4,5]sum_to_n?(a,11)#=>nil我如何知道何时可以将两个参数发送到预定义方法(如find)?我不清楚,因为有时它不起作用。这是重新定义的东西吗? 最佳答案 如果您查看Enumerable#find的文档,您会发现它只接受一个block参数。您可以将它发送两次的原因是因为Ruby可以方便地让您根据它的“并行赋
RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)