我在SQL服务器中有一个大表(下面显示的'ManyColSQLTable'示例),我希望在日期和时间样本上执行LEFT JOIN('myDateTimes'示例同时包含Date和Time列,并且可能包含不在ManyColSQLTable中的日期和时间。对于myDateTimes作为SQL服务器中的单独表存在的情况,下面的SQL代码正确地执行了此操作,但我想使用vb.net和LINQ动态地使用提交的myDateTimes数组执行此操作。
1)使用SQLDataAdapter将ManyColSQLTable拉入vb.net DataTable,然后使用LINQ与提交的myDateTimes一起编写LEFT JOIN。如何使用LINQ语法然后使用myDateTimes执行LEFT JOIN?请注意,myDateTimes被输入为vb.net数组。
2)或者,在包含MyDateTimes数组数据的数据库中创建临时表(如何操作?),然后使用下面的TSQL语法执行连接,然后将结果拉回到vb中会更有效吗? net(例如,使用SQLDataAdapter作为DataTable)。
SQL Server中的ManyColSQLTable示例:
Date Time EURUSD USDJPY GBPUSD USDCAD
1 2009-12-02 21:30:00 NULL NULL NULL NULL
2 2009-12-02 22:00:00 1.5047 87.4300 1.6636 1.0511
3 2009-12-02 22:30:00 1.5048 87.6100 1.6640 1.0512
4 2009-12-02 23:00:00 1.5061 87.5500 1.6652 1.0496
5 2009-12-02 23:30:00 1.5067 87.6400 1.6661 1.0493
... ... 00:00:00 ... ... ... ...
108 2009-12-20 04:30:00 1.5088 86.7100 1.6756 1.0393
以下适用于SQL Management Studio:
SELECT distinct *
FROM [dbo].myDateTimes as j
LEFT JOIN ManyColSQLTable ON
(ManyColSQLTable.Date = j.date and ManyColSQLTable.time = j.time)
Order by j.date desc , j.time desc
我尝试使用LINQ(语法显然是错误的 - 如何解决?):
Sub JoinExample()
Dim myDateTimes() As Date = {#6/19/2013 12:30:00 AM#, #12/3/2009 3:00:00 AM#}
Dim tbl As DataTable = FillDataTable()
' I'm stuck from this point on. How get the syntax correct?
Dim rsltTbl = From dt In myDateTimes
Join [Date] In tbl.AsEnumerable() On
dt Equals tbl.Columns([Date]) And dt.TimeOfDay Equals tbl.Columns([Time])
Select tbl.Rows()
End Sub
答案 0 :(得分:1)
<强>被修改强>
试试这个例子:
Module StartupModule
Sub Main()
' Mock data table.
Dim dt As New DataTable
dt.Columns.Add("Id", GetType(Integer))
dt.Columns.Add("Date", GetType(DateTime))
dt.Columns.Add("Description", GetType(String))
dt.Columns.Add("Amount", GetType(Decimal))
Dim addRow As Action(Of Integer, DateTime, String, Decimal?) = Sub(id, [date], description, amount)
Dim r = dt.NewRow
r.SetField("Id", id)
r.SetField("Date", [date])
If (Not String.IsNullOrEmpty(description)) Then
r.SetField("Description", description)
End If
If (amount.HasValue) Then
r.SetField("Amount", amount.Value)
End If
dt.Rows.Add(r)
End Sub
' Populate the table.
addRow(1, #1/1/2016 11:11:11 AM#, "First row", 100D)
addRow(2, #1/1/2017 10:10:10 AM#, "Second row", 200D)
addRow(3, #1/1/2018 9:09:09 AM#, Nothing, 300.05D)
addRow(4, #1/1/2019 8:08:08 AM#, "Fourth row", Nothing)
' Some dates in an array.
Dim dates As DateTime() = {
#1/1/2016 11:11:11 AM#,
#1/1/2017 10:10:11 AM#,
#1/1/2018 9:09:09 AM#,
#1/1/2019 8:08:08 AM#
}
' Dates array left join data table.
Dim rows = From arrayRow In dates
Group Join tableRow In dt
On tableRow.Field(Of DateTime)("date") Equals arrayRow Into tableRows = Group
From tableRow In tableRows.DefaultIfEmpty(dt.NewRow)
Select
arrayRow,
Id = If(tableRow.Field(Of Integer?)("Id").GetValueOrDefault = 0, "", tableRow.Field(Of Integer)("Id").ToString),
[Date] = If(tableRow.Field(Of DateTime?)("Date").GetValueOrDefault = DateTime.MinValue, "", tableRow.Field(Of DateTime)("Date").ToString("dd/MM/yyyy HH:mm:ss")),
Description = If(String.IsNullOrEmpty(tableRow.Field(Of String)("Description")), "", tableRow.Field(Of String)("Description")),
Amount = If(tableRow.Field(Of Decimal?)("Amount") Is Nothing, "", tableRow.Field(Of Decimal)("Amount").ToString("C"))
' Display results.
For Each row In rows
Console.WriteLine("LDate:{0} Id:{1} RDate:{2} Descr:{3} Amount:{4}", row.arrayRow, row.Id, row.Date, row.Description, row.Amount)
Next
Console.ReadLine()
End Sub
End Module
首先,我必须说这个实现(将DateTime
分成两列日期和时间)似乎很奇怪,使事情变得更加困难和容易出错。将DateTime
域(实际上描述了一个时刻)分成两个,即日期和时间,完全改变了第一个的含义。我强烈建议(如果你可以执行此更改)将其设为一列。
也就是说,我认为最好的方法是在您的select语句中将Date和Time列合并为一列,因此在您的数据表中会有一列DateTime
,因此您可以轻松地执行相等检查
我编辑了这个例子,以满足您的需求。
现在,关于您的主要问题,您可能需要查看How to: Combine Data with LINQ by Using Joins (Visual Basic)
希望这有帮助!
答案 1 :(得分:0)
你可以像这样在表之间做左外连接
var rowDataLeftOuter = from rowLeft in lefttbl.AsEnumerable()
join rowRight in rightble.AsEnumerable()
on rowLeft[colToJoinOn] equals rowRight[strTempColName] into gj
from subRight in gj.DefaultIfEmpty()
select lefttbl.ItemArray.Concat((subRight== null) ?
(rightble.NewRow().ItemArray) :subRight.ItemArray).ToArray();
代码在C#中,但您可以使用转换器转换为vb.net