none
如何使用CAST搜尋某一時間區段的資料個數 RRS feed

  • 問題

  • 各位大大好:

         我有一個關於搜尋的問題想要請教大家,要如果搜尋datatable內datetime型態的欄位中符合某一時間區段(ex: 17:00~18:59)的個數呢?

    table:<tmpTable>

    ---------------------------------------------

    DATE         |     Time                        |  value|
    ---------------------------------------------
    2006/10/22 |    2006/10/22 下午 05:59 |    20  |
    2006/10/22 |    2006/10/22 下午 01:25 |    45  |
    2006/10/22 |    2006/10/22 上午 09:50 |    45  |
    2006/10/23 |    2006/10/23 下午 05:59 |    20  |
    2006/10/23 |    2006/10/23 下午 01:25 |    45  |
    2006/10/23 |    2006/10/23 上午 09:50 |    45  |
    2006/10/25 |    2006/10/25 下午 05:59 |    20  |
    2006/10/25 |    2006/10/25 下午 01:25 |    45  |
    2006/10/25 |    2006/10/25 上午 09:50 |    45  |
    ----------------------------------------------

    我有嘗試過使用CAST,下面是我的寫法:

    double Bedtime = Convert.ToDouble(tmpTable.Compute("count(value)", "CAST(char(10), Time, 114) >= '9:00:00pm' and CAST(char(10), Time, 114) <= '11:59:59pm' "));//搜尋time欄位中時間介於晚上9點到晚上11點59分的個數

    執行會出現"運算式包含未定義的函式呼叫 CAST()。 "的錯誤。

    因為第一次使用cast,使用上不熟悉,再麻煩大大們指教,謝謝。

     

    2010年6月18日 上午 11:47

解答

  • 我剛試了一下, 我覺得你的需求用Convert做會有問題:

    (1) 在Expression中使用 Convert(日期時間欄位, 'System.String') 會得到12小時制的結果, 也就是字串會帶上下午, 一般來說, 日期時間值若要轉為文字來比較, 以24小時制來比較是麻煩會比較少的. 因為你在中文系統中可能會得到 "上午/下午", 英文系統則是 "AM/PM", 其它文字又不知會搞出什麼花樣來,而且還有會轉到時間前面還是後面的問題, 若要在不同語言及日期時間格式切換時, 這樣的差異會造成很多麻煩.

    (2)如果一定要用Datatable.Compute ,我比較建議的做法是另外建一個Column, 取得日期時間欄位中的24小時制時間轉換文字型態, ex:

      Dim myDataTable As New DataTable
            myDataTable.Columns.Add("Col0", System.Type.GetType("System.DateTime"))
            myDataTable.Columns.Add("Col1", System.Type.GetType("System.Int32"))
            myDataTable.Columns.Add("Col2", System.Type.GetType("System.String"))

            Dim str As String = ""
            For i As Integer = 0 To 5
                str = "2010/06/18 " & i.ToString("00") & ":00:00"
                Dim myRow As DataRow = myDataTable.NewRow()
                myRow(0) = System.Convert.ToDateTime(str)
                myRow(1) = i
                myDataTable.Rows.Add(myRow)
            Next
            For Each xRow As DataRow In myDataTable.Rows
                xRow("Col2") = System.Convert.ToDateTime(xRow("Col0")).ToString("HH:mm:ss")
            Next
            DataGridView1.DataSource = myDataTable

    (3) 不過真正比較好的建議是, 如果你是從資料庫 Select 出這個資料的話, 應該是在查詢時期就先把這個欄位值處理出來

    Select Col0, Col1, Convert(Col0,........... 這樣才對


    以下是簽名檔, 請勿沒事對號入座
    MSDN 文件庫很重要
    回應幫助你的人是一種禮貌, 良好的禮貌有助於激發大家對你問題回應的熱情
    進步的人會找尋自己程式中的缺點,半桶水則把自己程式的錯誤推到不相干事物的身上
    • 已標示為解答 piyolala 2010年6月20日 上午 09:44
    2010年6月18日 下午 01:47

所有回覆

  • 在DataTable.Compute中請使用Convert, 它沒有定義Cast的用法.

    請參閱[DataColumn.Expression 屬性 ]


    以下是簽名檔, 請勿沒事對號入座
    MSDN 文件庫很重要
    回應幫助你的人是一種禮貌, 良好的禮貌有助於激發大家對你問題回應的熱情
    進步的人會找尋自己程式中的缺點,半桶水則把自己程式的錯誤推到不相干事物的身上
    2010年6月18日 下午 01:10
  • 我剛試了一下, 我覺得你的需求用Convert做會有問題:

    (1) 在Expression中使用 Convert(日期時間欄位, 'System.String') 會得到12小時制的結果, 也就是字串會帶上下午, 一般來說, 日期時間值若要轉為文字來比較, 以24小時制來比較是麻煩會比較少的. 因為你在中文系統中可能會得到 "上午/下午", 英文系統則是 "AM/PM", 其它文字又不知會搞出什麼花樣來,而且還有會轉到時間前面還是後面的問題, 若要在不同語言及日期時間格式切換時, 這樣的差異會造成很多麻煩.

    (2)如果一定要用Datatable.Compute ,我比較建議的做法是另外建一個Column, 取得日期時間欄位中的24小時制時間轉換文字型態, ex:

      Dim myDataTable As New DataTable
            myDataTable.Columns.Add("Col0", System.Type.GetType("System.DateTime"))
            myDataTable.Columns.Add("Col1", System.Type.GetType("System.Int32"))
            myDataTable.Columns.Add("Col2", System.Type.GetType("System.String"))

            Dim str As String = ""
            For i As Integer = 0 To 5
                str = "2010/06/18 " & i.ToString("00") & ":00:00"
                Dim myRow As DataRow = myDataTable.NewRow()
                myRow(0) = System.Convert.ToDateTime(str)
                myRow(1) = i
                myDataTable.Rows.Add(myRow)
            Next
            For Each xRow As DataRow In myDataTable.Rows
                xRow("Col2") = System.Convert.ToDateTime(xRow("Col0")).ToString("HH:mm:ss")
            Next
            DataGridView1.DataSource = myDataTable

    (3) 不過真正比較好的建議是, 如果你是從資料庫 Select 出這個資料的話, 應該是在查詢時期就先把這個欄位值處理出來

    Select Col0, Col1, Convert(Col0,........... 這樣才對


    以下是簽名檔, 請勿沒事對號入座
    MSDN 文件庫很重要
    回應幫助你的人是一種禮貌, 良好的禮貌有助於激發大家對你問題回應的熱情
    進步的人會找尋自己程式中的缺點,半桶水則把自己程式的錯誤推到不相干事物的身上
    • 已標示為解答 piyolala 2010年6月20日 上午 09:44
    2010年6月18日 下午 01:47
  • 謝謝Bill大叔精闢的解答~

    想要請教一下您提供給我的範例中欄位Col1的作用是什麼?

    我的資料不是從資料庫撈出來的,是讀檔案內的預定格式,所以才會有點卡在後續的處理,不過我會考慮在讀檔時先做一些相關處理方便之後使用。

    2010年6月19日 下午 05:06
  • Col1我只是為了要有個欄位測試DataTable.Compute時用的, 就是我用Datatable.Compute("SUM(Col1)",...........), 沒有特別的意義.

    所以你讀取取類似文字檔這樣, 這樣其實就是在讀取時就順便把要當基準的那個欄位同時計算出來, 這樣比較省時一點.


    以下是簽名檔, 請勿沒事對號入座
    MSDN 文件庫很重要
    回應幫助你的人是一種禮貌, 良好的禮貌有助於激發大家對你問題回應的熱情
    進步的人會找尋自己程式中的缺點,半桶水則把自己程式的錯誤推到不相干事物的身上
    2010年6月19日 下午 05:31