#sql #sql-server #tsql
#sql #sql-сервер #tsql
Вопрос:
У меня в базе данных есть таблицы «T1», которые разбиты по месяцам формы (таблица_082020, таблица_092020, таблица_102020). Каждая содержит несколько миллионов записей.
---- ---------- -------
| id | date | value |
---- ---------- -------
| 1 | 20200816 | abc |
---- ---------- -------
| 2 | 20200817 | xyz |
---- ---------- -------
---- ---------- -------
| id | date | value |
---- ---------- -------
| 1 | 20200901 | cba |
---- ---------- -------
| 2 | 20200901 | zyx |
---- ---------- -------
Существует вторая таблица «T2», в которой хранится ссылка на первичный ключ первой и фактически на саму таблицу, только без слова «table_».
------------ -------- -------- -------- --------
| rec_number | period | field1 | field2 | field3 |
------------ -------- -------- -------- --------
| 777 | 092020 | aaa | bbb | ccc |
------------ -------- -------- -------- --------
| 987 | 102020 | eee | fff | ggg |
------------ -------- -------- -------- --------
| 123456 | 082020 | xxx | yyy | zzz |
------------ -------- -------- -------- --------
Существует также третья таблица «T3», которая представляет собой соотношение периода и имени таблицы.
-------- --------------
| period | table_name |
-------- --------------
| 082020 | table_082020 |
-------- --------------
| 092020 | table_092020 |
-------- --------------
| 102020 | table_102020 |
-------- --------------
Подскажите, как можно объединить 3 таблицы, чтобы получить динамические данные за несколько периодов. Например: от 15082020 до 04092020, где данные будут расположены в разных таблицах соответственно
Комментарии:
1. Исправьте свой дизайн. Не храните данные в имени таблицы. У вас должна быть одна таблица со столбцом для обозначения значения whatever
'082020'
,'092020'
represent .2. Зачем вам вообще нужно иметь несколько таблиц? У вас уже есть
date
столбец в таблице. Поместите все в одну таблицу, и вы можете выброситьT3
3. @DaleK Я попытался реализовать это решение с помощью курсора, выбрав данные и вставив их во временную таблицу. Это работает, но очень медленно
4. @Larnu Потому что за каждый месяц собирается около 5 миллионов записей. и чтобы упростить выбор данных
5. «и чтобы упростить выбор данных» , тогда вы сможете легко выполнить эту операцию, если это так «просто» при использовании этого подхода. 😉 Очевидно, что это не так , как если бы это было «легко», вы бы не задавали этот вопрос. Что проще , так это добавить
WHERE YourVarcharColumn = '092020'
, не имея 10 таблиц. В противном случае изучите разбиение на разделы. Реальное решение — исправить дизайн.
Ответ №1:
На самом деле нет веской причины для хранения данных в этом формате. Это превращает выполнение запросов в кошмар.
Если вы не можете изменить формат данных, каждый месяц добавляйте представление, объединяющее данные:
create view t as
select '202010' as YYYYMM, t.*
from table_102020
union all
select '202008' as YYYYMM, t.*
from table_092020
union all
. . .;
Раз в месяц вы можете потратить 10 минут на написание кода и делать это с напоминанием календаря. Или, что еще лучше, настройте задание, которое использует динамический SQL для генерации кода, и запустите его как задание после использования базовых таблиц.
Что вы должны делать? Ну, 5 миллионов строк в месяц — это на самом деле не так много данных. Но если вас это беспокоит, вы можете использовать разделение таблиц для хранения данных по месяцам. Это может быть немного сложнее; например, первичный ключ должен включать ключ разделения.
Комментарии:
1. Спасибо! Я придумал решение: я создал хранимую процедуру и передаю ей два параметра: период от и до. И я формирую sql-запрос в цикле