datatables - 将一个表的值添加/合并到另一个表

时间:2011-05-06 11:14:55

标签: asp.net vb.net datatable

新项目要求我们设置两台服务器来接受请求。最初我们有一个报告系统,它查询数据库并将各种细节带回给用户。我们现在显然需要在单独的服务器上查询两个数据库并合并此信息以提供实时报告。

我的计划是单独查询两个数据库并将这些值写入数据表(它们将始终具有相同的列,因为两个数据库的设计相同)然后尝试合并这两个数据表,然后将其数据绑定到网格视图。我有点工作到一点,但不知道下一步做什么...查询都工作正常,我能够将两组sql查询拉成单独的数据表,我不知道怎么做是合并这些以便添加任何数据(例如相同日期)以从两个服务器中提供总数,并且在一个数据库上存在日期但不存在另一个数据库,这仍应显示...我希望这是明确的够了。

当我使用它时:

tblBreakdownA.Merge(tblBreakdownB, False, MissingSchemaAction.Add)

        GridViewBreakDown.DataSource = tblBreakdownA
        GridViewBreakDown.DataBind()

这两个数据表确实合并,但第二个只是合并在第一个以下,所以我最终重复了一些日期,但保持不同的值,即

DB 1
01 jan - 10次点击
03 jan - 15次点击
04 jan - 5次点击

DB 2
02 jan - 5次点击
03 jan - 10次点击
05 jan - 5次点击

我看到的输出是这样的:
01 jan - 10次点击
03 jan - 15次点击
04 jan - 5次点击
02 jan - 5次点击
03 jan - 10次点击
05 jan - 5次点击

我正在寻找的应该是这样的 01 jan - 10次点击
02 jan - 5次点击
03月1日 - 25次点击
04 jan - 5次点击
05 jan - 5次点击

任何帮助一如既往地非常感谢!

编辑 - 已添加源代码

下面是更多代码,以更好地解释我想要实现的目标。

'*******POPULATE GRIDVIEW-BREAKDOWN CONTROL**************
    Dim tblBreakdownA As DataTable 'holds results from Database A
    Dim tblBreakdownB As DataTable 'holds results from Database B

    GridViewBreakDown.Visible = True
    lblBreakdown.Visible = True

    'Connection to Database A
    Using myConnection As New SqlConnection
        myConnection.ConnectionString = CONNECTION STRING
        Dim mySelect As New SqlCommand
        mySelect.Connection = myConnection
        mySelect.CommandText = "SELECT STATEMENT"
        myConnection.Open()
        Dim myReader As SqlDataReader = mySelect.ExecuteReader()

        tblBreakdownA = New DataTable("Breakdown")
        tblBreakdownA.Load(myReader)

        myReader.Close()
        myConnection.Close()
    End Using

    'Connection to Database B
    Using myConnection As New SqlConnection
        myConnection.ConnectionString =CONNECTION STRING
        Dim mySelect As New SqlCommand
        mySelect.Connection = myConnection
        mySelect.CommandText = "SELECT STATEMENT"
        myConnection.Open()
        Dim myReader As SqlDataReader = mySelect.ExecuteReader()

        tblBreakdownB = New DataTable("Breakdown")
        tblBreakdownB.Load(myReader)

        myReader.Close()
        myConnection.Close()
    End Using

    tblBreakdownA.Merge(tblBreakdownB, False, MissingSchemaAction.Add)

    GridViewBreakDown.DataSource = tblBreakdownA
    GridViewBreakDown.DataBind()

2 个答案:

答案 0 :(得分:0)

我认为你要找的是分组。您可以使用Linq或T-SQL执行此操作,但实际上您希望按日期对记录进行分组,并显示该组中命中的总和。

分组示例:

Linq to SQL Group By

T-SQL Group By

编辑:

我希望@ Rene147不介意我调整他发布的代码来演示你需要的Linq语法(它有点啰嗦和乱七八糟但是它起作用并演示了一些Linqs的整洁功能......) :

Public Sub StackTest()
    Dim dt1 As New DataTable
    Dim dt2 As New DataTable

    '   Create some test data
    dt1.Columns.Add("Date", GetType(Date))
    dt1.Columns.Add("Hits", GetType(Integer))

    dt2.Columns.Add("Date", GetType(Date))
    dt2.Columns.Add("Hits", GetType(Integer))


    dt1.Rows.Add(#1/1/2011#, 10)
    dt1.Rows.Add(#3/1/2011#, 15)
    dt1.Rows.Add(#4/1/2011#, 5)

    dt2.Rows.Add(#2/1/2011#, 5)
    dt2.Rows.Add(#3/1/2011#, 10)
    dt2.Rows.Add(#5/1/2011#, 5)

    '   Merge the two results
    dt1.Merge(dt2)

    dt1.DefaultView.Sort = "Date"

    Dim results = (From anomList In
                   (From mergedTables In dt1.DefaultView.ToTable(True, "Date", "Hits").AsEnumerable
                    Select [Date] = mergedTables.Item(0), Hits = mergedTables.Item(1))
                Group anomList By anomList.Date Into g = Group
                Select New With {.[Date] = [Date], .Hits = g.Sum(Function(n) CInt(n.Hits))}).OrderBy(Function(n) n.Date)
End Sub  

答案 1 :(得分:0)

这将按照您的要求执行,但100%同意Smudge,在SQL语句中执行GroupBy会好得多

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim dt1 As New DataTable
    Dim dt2 As New DataTable

    '   Create some test data
    dt1.Columns.Add("Date", GetType(Date))
    dt1.Columns.Add("Hits", GetType(Integer))

    dt2.Columns.Add("Date", GetType(Date))
    dt2.Columns.Add("Hits", GetType(Integer))


    dt1.Rows.Add(CDate("01/01/2011"), 10)
    dt1.Rows.Add(CDate("03/01/2011"), 15)
    dt1.Rows.Add(CDate("04/01/2011"), 5)

    dt2.Rows.Add(CDate("02/01/2011"), 5)
    dt2.Rows.Add(CDate("03/01/2011"), 10)
    dt2.Rows.Add(CDate("05/01/2011"), 5)

    '   Merge the two results
    dt1.Merge(dt2)

    dt1.DefaultView.Sort = "Date"

    '    Select all of the distinct dates 
    For Each row As DataRow In dt1.DefaultView.ToTable(True, "Date").Rows

        Dim TotalForDay As Integer = 0

        TotalForDay = HitsOnGivenDate(row.Item(0), dt1)
        TotalForDay += HitsOnGivenDate(row.Item(0), dt2)

        Debug.WriteLine(String.Format("Date - {0} had {1} hits", row.Item(0), TotalForDay))
    Next

End Sub

Private Function HitsOnGivenDate(ByVal SearchDate As Date, ByVal SearchTable As DataTable) As Integer

    Dim HitsOnDay As Integer = 0

    Dim SearchString As String = String.Format("Date = '{0}'", SearchDate)

    '   Selete all the rows for this given date
    For Each Row As DataRow In SearchTable.Select(SearchString)
        HitsOnDay += Row.Item(1)
    Next

    Return HitsOnDay
End Function