在Linq to SQL中按周(按周数)分组

时间:2010-08-06 21:22:52

标签: c# sql-server vb.net linq-to-sql week-number

在常规SQL中,我可以执行类似

的操作
SELECT * From T GROUP BY DATEPART(wk, T.Date)

我如何在Linq to SQL中执行此操作?

以下不起作用

From F In DB.T Group R By DatePart(DateInterval.WeekOfYear, F.Date)

也不行:

From F In DB.T Group R By (F.Date.DayOfYear / 7)

6 个答案:

答案 0 :(得分:7)

LINQ to SQL不支持Calendar.WeekOfYear方法,但您可能会创建TSQL function that wraps the call to DatePart。 DayOfYear / 7技巧应该适用于大多数情况,并且更容易使用。这是我最终得到的代码:

var x = from F in DB.T
        group F by new {Year = F.Date.Year, Week = Math.Floor((decimal)F.Date.DayOfYear / 7)} into FGroup
        orderby FGroup.Key.Year, FGroup.Key.Week
        select new {
            Year = FGroup.Key.Year,
            Week = FGroup.Key.Week,
            Count = FGroup.Count()
        };

结果如下:

Year    Week    Count
2004    46      3
2004    47      3
2004    48      3
2004    49      3
2004    50      2
2005    0       1
2005    1       8
2005    2       3
2005    3       1
2005    12      2
2005    13      2

答案 1 :(得分:1)

这是正常的。

from F in DB.T group F by F.Date.DayOfYear / 7;

您错误地指定了该组。此代码的结果是对象的集合。每个对象都有一个Key属性,它将是你的分组(在这种情况下是F.Date.DayOfYear / 7的结果。每个对象都是来自T的符合组条件的对象的集合。

答案 2 :(得分:1)

答案 3 :(得分:1)

您可以使用System.Data.Entity.SqlServer名称空间中的SqlFunctions.DatePart方法。

// Return the week number
From F In DB.T Group R By SqlFunctions.DatePart("week", F.Date)

答案 4 :(得分:0)

如果您关注以下代码中的文化,则会考虑到这一点:

var ci = CultureInfo.CurrentCulture;
var cal = ci.Calendar;
var rule = ci.DateTimeFormat.CalendarWeekRule;
var firstDayOfWeek = ci.DateTimeFormat.FirstDayOfWeek;

var groups = from F in DB.T
             group F by cal.GetWeekOfYear(F, rule, firstDayOfWeek) into R
             select R;

答案 5 :(得分:0)

首先,你应该得到一周中第一天的日期。

获取一周中第一天的日期。 你可以使用这段代码:

@staticmethod
    def fetch_rows(cursor):
        frame = cursor.fetchone()
        while frame is not None:
            yield frame
            frame = cursor.fetchone()

@staticmethod
def __generate_field(body):
    """
    Takes an action and creates an iterator element json join body
    :param body: adds json body to generator
    :return: item iterator
    """
    for item in body:
        yield item

def json_for_bulk_body_sql_list(self, body, index_name: str, name_of_docs: str):
    """
    :param body: List that will be made as a generator
    :param index_name : name of the index based on location
    :param name_of_docs : name of the docs that you want of in the index
    :return: Structured JSON file for bulking
    """

    # if not isinstance(body, list):
    #     raise TypeError('Body must be a list')
    if not isinstance(index_name, str):
        raise TypeError('index must be a string')

    structured_json_body = ({
        '_op_type': 'index',
        '_index': index_name,  # index name Twitter
        '_type': name_of_docs,  # type is tweet
        '_id': doc['tweet_id'],  # id of the tweet
        '_source': doc
    } for doc in self.__generate_field(body))
    return structured_json_body


json_results = (dict(zip(column_names, row)) for row in self.fetch_rows(cursor))
actions = (self.json_for_bulk_body_sql_list(json_results, index_name=index_, name_of_docs=doc_name))

for success, info in self.bulk_es_parallel(actions=actions):
    if not success:
        print('Doc failed: '.upper(), info)
    else:
        ingested += 1

然后您可以按一周的第一个日期进行分组。

所以常规SQL中的代码:

public static class DateTimeExtensions
{
    public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
    {
        int diff = dt.DayOfWeek - startOfWeek;
        if (diff < 0)
        {
            diff += 7;
        }
        return dt.AddDays(-1 * diff).Date;
    }
}

可以在Linq to SQL中完成,就像这样

SELECT * From T GROUP BY DATEPART(wk, T.Date)