Как разбить таблицу по месяцам ("оба" года и месяца) и автоматически создавать ежемесячные разделы?
Я пытаюсь разделить таблицу на оба год и месяц. Столбец, через который я буду разбивать, является столбцом типа datetime с форматом ISO ('20150110', 20150202 ' и т. д.).
например, у меня есть данные о продажах за 2010, 2011, 2012 годы. Я бы хотел, чтобы данные были разделены по годам и каждый год также разделялись по месяцам. (2010/01, 2010/02,... 2010/12, 2011/01, ... 2015/01...)
E. X:
Sales2010Jan, Sales2010Feb, Sales2011Jan, Sales2011Feb, Sales2012Dec и др.
мой вопрос: возможно ли это вообще? Если это так, как я автоматизирую процесс с помощью SSIS?
1 ответов
SSIS-это ETL (извлечение, преобразование, загрузка). Это не то, что ты хочешь сделать. Вам просто нужно динамически создавать операторы DDL .
Я работаю с кварталом ниже, но он также работает с 1, 2 или X месяцев, если вы хотите.
если вы хотите разделить таблицу, вам сначала нужно создать файл, файловые группы и разделенную таблицу и установить partitionning вручную
создание N + 1 разделов на 2015 Q1 (до, Q1 и после Q2)в таблице с идентификатором int PK и секционированным столбцом datetime2. Обновите его, чтобы добавить месяцы, сделать его ежемесячным или все, что вам нужно...
-
сначала создайте N групп файлов:
Alter Database [Test] Add Filegroup [Part_Before2015] Go Alter Database Test Add Filegroup [Part_201501] Go Alter Database Test Add Filegroup [Part_201504] Go
-
Добавить файл для каждой файловой группы:
Alter Database [Test] Add FILE ( NAME = N'Part_Before2015', FILENAME = N'...\Part_Before2015.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB ) TO Filegroup [Part_Before2015] Alter Database [Test] Add FILE ( NAME = N'Part_201501', FILENAME = N'...\Part_201501.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB ) TO Filegroup [Part_201501] Alter Database [Test] Add FILE ( NAME = N'Part_201504', FILENAME = N'...\Part_201504.ndf' , SIZE = 5120KB , FILEGROWTH = 1024KB ) TO Filegroup [Part_201504]
-
создайте функцию секционирования для типа datetime2 (или date или даже datetime):
Create Partition Function RangePartFunction (datetime2) as Range Right For Values ('20150101', '20150401')
-
создайте схему разделов, используя функция секционирования для каждой файловой группы (N+1):
Create Partition Scheme RangePartScheme as Partition RangePartFunction To ([Part_Before2015], [Part_201501], [Part_201504])
-
создайте секционированную таблицу в ее схеме секционирования:
Create TABLE [PartitionTable] (id int identity(0, 1) not null, date datetime2 not null, text char(8000)) On RangePartScheme (date) ;
-
добавить кластеризованный индекс в секционированный столбец и схему секционирования:
Create Clustered Index IDX_Part On dbo.PartitionTable(date) On RangePartScheme (date);
-
добавьте PK в столбец id:
Alter Table dbo.PartitionTable Add COntraint PK_Part Primary Key Nonclustered(id, date);
создайте запрос, используемый для добавления дополнительных групп файлов после правой границы и разделения последней раздел
- обзор схемы секционирования расширения и функции секционирования split
- обзор DMV используется
-
обзор все это и как использовать его для создания динамического SQL
Declare @currentDate datetime2 Declare @endDate datetime2 = '20160701' -- new end date Declare @dateAdd int = 3 -- Add 3 month = 1 Quarter -- Get Current boundaries Select @currentDate = DATEADD(MONTH, @dateAdd,Cast(MAX(value) as datetime2)) From sys.partition_range_values as r Inner Join sys.partition_functions as f on r.function_id = f.function_id Where f.name = 'RangePartFunction' -- Get all quarters between max and end date ; with d(id, date, name) as ( Select 0, @currentDate, Convert(char(6), @currentDate, 112) Union All Select id+1, DATEADD(MONTH, @dateAdd, date), Convert(char(6), DATEADD(MONTH, @dateAdd, date), 112) From d Where d.date <= @endDate ) Select * From ( Select id = id*10, query = 'If Not Exists(Select 1 From sys.filegroups Where name = ''Part_'+name+''') Begin Print ''Create Filegroup [Part_'+name+']'' Alter Database [Test] Add Filegroup [Part_'+name+'] End GO' From d Union All Select id*10+1, 'If Not Exists(Select 1 From sys.sysfiles Where name = ''Part_'+name+''') Begin Print ''Create File [Part_'+name+'.ndf]'' Alter Database [Test] Add FILE ( NAME = N''Part_'+name+''', FILENAME = N''C:\DB\MSSQL11.MSSQLSERVER\MSSQL\DATA\Part_'+name+'.ndf'' , SIZE = 5120KB , FILEGROWTH = 1024KB ) TO Filegroup [Part_'+name+'] End GO' From d Union All Select id*10+2, 'Print ''Add Range [Part_'+name+']'' Alter Partition Scheme RangePartScheme Next Used [Part_'+name+'] Go' From d Union All Select id*10+3, 'Print ''Split Function ['+Convert(char(8), date, 112)+']'' Alter Partition Function RangePartFunction() Split Range ('''+Convert(char(8), date, 112)+'''); Go' From d ) as q order by id
выводом этого запроса является список SQL-запросов, которые должны выполняться по порядку.
выполнить динамический SQL
- он может быть выполнен вручную (копирование и прошлое в SSMS)
- он может быть выполнен в цикле while или с курсором, который будет выполнять каждую строку таблицы ouput один за другим (используйте sp_executesql)
автоматизация
- создайте задание SQL Server, которое вызывает SQL-запросы: запустите запрос, используемый для создания динамического SQL, сохраните его вывод в переменную таблицы, а затем выполните каждый оператор с помощью цикла / курсора
если вы хотите запустить его ежемесячно и сделать конечно, следующие 12 месяцев всегда создаются, используйте это Set @endDate = DATEADD(MONTH, 12, getdate())
наконец-то
-
он выведет 4 * N строк для N недостающих кварталов между последней границей функции и @endDate:
- Создать Файловую Группу
- создать файл в файловой группе
- расширить диапазон схемы секционирования
- разделить диапазон раздела функция
вы можете запустить его строка за строкой с помощью курсора или цикла while, или вы можете просто скопировать и вставить его в SMSS.
- он может быть автоматизирован с заданием, а ie.
@endDate = DATEADD(MONTH, 3, getdate()
создаст следующие 3 месяца - измените @dateAdd на 1, Если вы хотите ежемесячные разделы
- добавить собственные столбцы или проверки
ссылке
Создать задачу = https://www.mssqltips.com/sqlservertip/3052/simple-way-to-create-a-sql-server-job-using-tsql/
sp_executesql = https://technet.microsoft.com/en-us/library/ms188001%28v=sql.110%29.aspx
цикл while = https://dba.stackexchange.com/questions/57933/can-exec-work-with-while-loop-of-cursor