Sajid227 Ответов: 2

Как запросить groupby в следующей ситуации


У меня есть datatable в следующем формате

Id   LocationId  UserName  Startdate
1       10        xz        2017-02-21 09:05:20
2       10        xz        2017-02-21 09:15:20
3       10        xz        2017-02-21 09:25:20
4       10        xz        2017-02-21 09:35:20
5       11        xz        2017-02-21 09:45:20
6       11        xz        2017-02-21 09:55:20
7       11        xz        2017-02-21 10:05:20
8       11        xz        2017-02-21 10:15:20



Я хочу вычислить время начала и окончания и разницу во времени ,

и есть показать запись как
Id      locationId  startdate          starttime             endtime    timespan   
1            10      2017-02-21          09:05              09:35:20  0hr 30min0sec               
1            10    2017-02-21            09:05             09:35:20   0hr 30min0sec


Что я уже пробовал:

<pre> If dt IsNot Nothing AndAlso dt.Rows.Count > 0 Then
            hdnreviewerHistoryCount.Value = UserManager.GetReviewerHistoryByActivityTypeCount(Request.QueryString("Id"), StartDate, EndDate, activity)
            Dim StartTime As New TimeSpan
            Dim EndTime As New TimeSpan
            Dim totalTime As New TimeSpan
            totalTime = Convert.ToDateTime(dt.Rows(dt.Rows.Count - 1)("AddedOn")).Subtract(dt.Rows(0)("AddedOn"))
            Dim index As Integer = 0
            Dim filterdata As New Filterdata
            Dim prevTime As New DateTime
            Dim prevLocation As Integer
            For Each row As DataRow In dt.Rows
                If index = 0 AndAlso row("CheckInLocation") IsNot DBNull.Value Then
                    prevTime = row("AddedOn")
                    prevLocation = row("CheckInLocation")
                Else
                    If prevLocation = row("CheckInLocation") Then
                        Dim timeDiff As TimeSpan = Convert.ToDateTime(row("AddedOn")).Subtract(prevTime)
                        EndTime = EndTime.Add(timeDiff)
                        prevLocation = IIf(row("LocationAddress") Is DBNull.Value, 0, row("LocationAddress"))
                        prevTime = row("AddedOn")
                    Else

                    End If

                End If
                index += 1
            Next
            rptreviewerhistory.DataSource = filterlist
            rptreviewerhistory.DataBind()
        End If
    End Sub
    Public Class Filterdata
        Public Property customdate As DateTime
        Public Property fromdate As DateTime
        Public Property todate As DateTime
        Public Property timespent As DateTime
        Public Property LocationName As String

    End Class

2 Ответов

Рейтинг:
0

Graeme_Grant

Если вы извлекаете данные из базы данных, то вы можете использовать SQL ГРУППА ПО[^]. Если вы хотите сделать это в коде, то вы можете использовать Linq ГРУППА ПО[^] пункт.


Рейтинг:
0

Maciej Los

Попробовать это:

'needed to convert string into date
Dim provider As System.Globalization.CultureInfo = System.Globalization.CultureInfo.InvariantCulture
'create sample datatable
Dim dt As DataTable = New DataTable()
dt.Columns.Add(New DataColumn("Id", Type.GetType("System.Int32")))
dt.Columns.Add(New DataColumn("LocationId", Type.GetType("System.Int32")))
dt.Columns.Add(New DataColumn("UserName", Type.GetType("System.String")))
dt.Columns.Add(New DataColumn("Startdate", Type.GetType("System.DateTime")))
'insert data
dt.Rows.Add(New Object(){1, 10, "xz", DateTime.ParseExact("2017-02-21 09:05:20", "yyyy-MM-dd HH:mm:ss", provider)})
dt.Rows.Add(New Object(){2, 10, "xz", DateTime.ParseExact("2017-02-21 09:15:20", "yyyy-MM-dd HH:mm:ss", provider)})
dt.Rows.Add(New Object(){3, 10, "xz", DateTime.ParseExact("2017-02-21 09:25:20", "yyyy-MM-dd HH:mm:ss", provider)})
dt.Rows.Add(New Object(){4, 10, "xz", DateTime.ParseExact("2017-02-21 09:35:20", "yyyy-MM-dd HH:mm:ss", provider)})
dt.Rows.Add(New Object(){5, 11, "xz", DateTime.ParseExact("2017-02-21 09:45:20", "yyyy-MM-dd HH:mm:ss", provider)})
dt.Rows.Add(New Object(){6, 11, "xz", DateTime.ParseExact("2017-02-21 09:55:20", "yyyy-MM-dd HH:mm:ss", provider)})
dt.Rows.Add(New Object(){7, 11, "xz", DateTime.ParseExact("2017-02-21 10:05:20", "yyyy-MM-dd HH:mm:ss", provider)})
dt.Rows.Add(New Object(){8, 11, "xz", DateTime.ParseExact("2017-02-21 10:15:20", "yyyy-MM-dd HH:mm:ss", provider)})

'group data by LocationId and UserName
'calculate time difference
Dim result = dt.AsEnumerable() _
	.GroupBy(Function(x) New With { _
			.LocationId=x.Field(Of Integer)("LocationId"), _
			.UserName=x.Field(Of String)("UserName")}) _
	.Select(Function(grp) New With _
		{ _
			.LocationId = grp.Key.LocationId, _
			.UserName = grp.Key.UserName, _
			.StartTime = grp.Select(Function(a) a.Field(Of DateTime)("StartDate")).Min().ToString("HH:mm:ss"), _
			.EndTime = grp.Select(Function(a) a.Field(Of DateTime)("StartDate")).Max().ToString("HH:mm:ss"), _
			.TimeDiff = grp.Select(Function(a) a.Field(Of DateTime)("StartDate")).Max() - grp.Select(Function(a) a.Field(Of DateTime)("StartDate")).Min() _
		}) _
	.ToList()


Выше должно вернуться:
LocationId UserName StartTime EndTime  TimeDiff
10         xz       09:05:20  09:35:20 00:30:00 
11         xz       09:45:20  10:15:20 00:30:00 


Sajid227

но проблема в том ,что если один и тот же идентификатор местоположения повторится снова,я должен показать его в отдельном результате,если я применю группу к тому времени, она сгруппирует все совпадающие идентификаторы местоположения, как я могу это решить???

Maciej Los

Извините, я вас не понимаю...
Разве приведенный выше пример кода не показывает, как этого добиться?