В настоящее время я изучаю SQL, и мне нужен был запрос, который вернул бы данные за предыдущие 12 недель (исключая текущую неделю), и приведенное ниже работало нормально - это было до тех пор, пока мы не перешли в 2019 год!

В моей таблице 4 столбца: BuildWeek, BuildYear, Info1, Info2, все они целые.

select * 
from Dashboard 
where BuildWeek in (datepart(week, getdate()) - 1, 
                    datepart(week, getdate()) - 2,  
                    datepart(week, getdate()) - 3,  
                    datepart(week, getdate()) - 4,  
                    datepart(week, getdate()) - 5,
                    datepart(week, getdate()) - 6, 
                    datepart(week, getdate()) - 7, 
                    datepart(week, getdate()) - 8, 
                    datepart(week, getdate()) - 9, 
                    datepart(week, getdate()) - 10, 
                    datepart(week, getdate()) - 11, 
                    datepart(week, getdate()) - 12, 
                    datepart(week, getdate()) - 13)
  and BuildYear = datepart(year, getdate()) 
order by 
    BuildWeek desc

Я знаю, что это не самый чистый запрос, поэтому я готов получить образование, я пробовал несколько вещей (безрезультатно используя dateadd), но не могу заставить его работать так, как я хочу. Я предполагаю, что вышеприведенное проистекает из запроса, возможно, глядя на минус (текущая дата -1 будет 0, -2 будет -1, поэтому результатов не будет?), Но я не уверен, как заставить его смотреть назад чтобы вернуть эти лишние недели.

3
John Hunter 6 Янв 2019 в 20:28

2 ответа

Лучший ответ

Другое решение - создать дату из BuildWeek и BuildYear (скажем, первого дня недели), которые можно использовать в предложении WHERE.

Преимущество этого подхода заключается в том, что гарантированно возвращаются записи за последние 12 недель, даже если их не ровно 12 (например, если у вас есть пробелы в сериях недель) или если существуют будущие записи.

SELECT d.*
FROM Dashboard d
WHERE 
    DATEADD( wk, DATEDIFF( wk, 7, CAST( d.BuildYear AS NVARCHAR(100) ) ) + (d.BuildWeek-1) , 7 )
        BETWEEN DATEADD( week, -12, GETDATE() ) AND GETDATE()
ORDER BY 
    d.BuildYear DESC,
    d.BuildWeek DESC

Протестировано в этой скрипте базы данных.

0
GMB 7 Янв 2019 в 08:31

Предполагая, что у вас есть одна строка в неделю:

select top (12) d.*
from Dashboard d
order by d.year desc, d.BuildWeek desc;

Чтобы избежать будущих недель:

select top (12) d.*
from Dashboard d
where year < year(getdate()) or
      (year = year(getdate()) and buildweek <= datepart(week, getdate())
order by d.year desc, d.BuildWeek desc;

Или, если вы хотите использовать where и в годах 52 недели:

select d.*
from dashboard d
where (y.year * 52 + buildweek) >= year(getdate()) * 52 + datepart(week, getdate());

Этот метод становится немного сложнее, если в годах может быть 53 недели.

0
Gordon Linoff 6 Янв 2019 в 18:47