Доступ SQL SELECT * WHERE Weeknum - PullRequest
1 голос
/ 27 мая 2020

Я уверен, что упускаю что-то очевидное, но не могу этого понять. Моя проблема очень проста: у меня есть таблица, содержащая следующую информацию:

Год, Номер недели, Данные

Я хочу ВЫБРАТЬ только данные, где номер недели меньше, чем текущая неделя. Это просто. Но что мне действительно нужно, так это все данные, зарегистрированные до текущего номера недели И текущего года. Это означает, что у меня есть следующие данные:

Year   Week   Data
2019    20    123
2019    21    234
2020    20    345
2020    21    456

Если текущая неделя - 21 2020 года, то я хочу, чтобы результат был:

year   Week   Data
2019    20     123
2019    21     234
2020    20     234

Я не хочу 2020-21, потому что это это текущий год / неделя. Мой текущий запрос:

SELECT T.Year, T.Week, T.Data
FROM tblData AS T
WHERE Year<=year(Date()) AND Week<Weeknumber(Date())

Проблема с этим запросом в том, что он не показывает недели старше 21 года в 2019 году, что я хочу сделать. Я знаю, почему этот sql не работает, но не могу понять, как это сделать правильно.

Как мне это сделать?

Ответы [ 3 ]

1 голос
/ 27 мая 2020

Поскольку вы из Дании, таблица, скорее всего, будет отражать годы и недели согласно ISO 8601 . Однако ни одна собственная функция VBA не вернет год и неделю даты по ISO 8601, а для дат около Нового года год часто будет отличаться от календарного года.

Таким образом, функции для возврата ISO Требуется 8601 год и неделя:

    Public Const MaxWeekValue           As Integer = 53
    Public Const MinWeekValue           As Integer = 1
    Public Const MaxMonthValue          As Integer = 12
    Public Const MinMonthValue          As Integer = 1


' Returns the ISO 8601 week of a date.
' The related ISO year is returned by ref.
'
' 2016-01-06. Gustav Brock, Cactus Data ApS, CPH.
'
Public Function Week( _
    ByVal Date1 As Date, _
    Optional ByRef IsoYear As Integer) _
    As Integer

    Dim Month       As Integer
    Dim Interval    As String
    Dim Result      As Integer

    Interval = "ww"

    Month = VBA.Month(Date1)
    ' Initially, set the ISO year to the calendar year.
    IsoYear = VBA.Year(Date1)

    Result = DatePart(Interval, Date1, vbMonday, vbFirstFourDays)
    If Result = MaxWeekValue Then
        If DatePart(Interval, DateAdd(Interval, 1, Date1), vbMonday, vbFirstFourDays) = MinWeekValue Then
            ' OK. The next week is the first week of the following year.
        Else
            ' This is really the first week of the next ISO year.
            ' Correct for DatePart bug.
            Result = MinWeekValue
        End If
    End If

    ' Adjust year where week number belongs to next or previous year.
    If Month = MinMonthValue Then
        If Result >= MaxWeekValue - 1 Then
            ' This is an early date of January belonging to the last week of the previous ISO year.
            IsoYear = IsoYear - 1
        End If
    ElseIf Month = MaxMonthValue Then
        If Result = MinWeekValue Then
            ' This is a late date of December belonging to the first week of the next ISO year.
            IsoYear = IsoYear + 1
        End If
    End If

    ' IsoYear is returned by reference.
    Week = Result

End Function


' Returns the ISO 8601 year of a date.
'
' 2016-01-06. Gustav Brock, Cactus Data ApS, CPH.
'
Public Function YearOfWeek( _
    ByVal Date1 As Date) _
    As Integer

    Dim IsoYear As Integer

    ' Get the ISO 8601 year of Date1.
    Week Date1, IsoYear

    YearOfWeek = IsoYear

End Function

Пример:

? Week(#2024/12/31#)
 1 

? YearOfWeek(#2024/12/31#)
 2025

Теперь используйте их в своем запросе:

SELECT 
    T.Year, 
    T.Week, 
    T.Data
FROM 
    tblData AS T
WHERE 
    T.Year * 100 + T.Week < YearOfWeek(Date()) * 100 + Week(Date())

И вы можете безопасно сохранить Год в качестве имени поля, если вы добавляете к нему префикс в запросах с именем таблицы, как вы уже делаете, или заключаете его в квадратные скобки: [Year].

1 голос
/ 27 мая 2020

Год - зарезервированное слово и не должно использовать зарезервированные слова в качестве имен для чего-либо. Я использовал Yr в качестве имени поля.

Учитывайте:

SELECT Yr, Week, Data
FROM Table1
WHERE [Week] Between 1 And IIf([Yr]=Year(Date()), DatePart("ww", Date()) - 1, 53);
0 голосов
/ 27 мая 2020

После дальнейшего тестирования июнь 7 был очень близок, но этот sql закончился удалением недель, превышающих текущую неделю в 2019 году (чего я не хотел). Возможно, я не был достаточно ясен в своем вопросе, но вот критерии sql WHERE, которые дали мне то, что я хотел. То есть я хочу, чтобы запрос удалял данные только за текущую неделю текущего года. все, что старше этого, я хочу показать.

WHERE tbl.Week Between 1 And IIf(tbl.Yr=Year(Date()),Datepart("ww",Date())-1,53) 

но спасибо за вашу помощь @ June7, так как вы привели меня прямо к ответу

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...