SQL Server - поиск определенного столбца на основе значения - PullRequest
0 голосов
/ 13 февраля 2011

Я получил очень широкую таблицу месячных индексов, которая выглядит следующим образом:

index_id | ... | Mar2009 | Apr2009 | May2009 | ... | Feb2010 |
1        | ... | value1  | value2  | value3  | ... | value11 |

Есть 180 столбцов, имена в серии, которые представляют месяц и год (март 2009, апрель 2009, ...), и естьоколо 5000 записей, эта таблица обновляется ежемесячно.

Я также получил вторую таблицу с такими данными, как:

index | some other data | index_id | saledate | saleprice | estimated price |
1234  | other data ...  |        1 | 03/05/09 |       100 | ??????????????? |

(около 1 миллиона записей), и мне нужно доставить полную запись на основе индексавключая estimated_price, который рассчитывается как: saleprice * ( value1 / value11 ) значение1, поскольку идентификатор saledate в марте 2009 года, значение11 из-за текущего месяца.

У меня есть 2 варианта, оба требуют доступа к конкретному столбцу в зависимости от значения, второй может иметьОбойти:

  1. Рассчитать на лету (и , как я могу получить доступ к правильному столбцу в таблице индексов на основе данных о состоянии и текущих данных ) - помните, что таблица данных большаяи индексы тоже не samll

  2. Когда таблица индексов обновления запускает задание для расчета оценочной цены, поместите ее в таблицу данных, как и в случае с тем же вопросом, что и выше ( как получить доступ кстолбец rrect в таблице индексов на основе saledate )

Второе решение выглядит более эффективным на первый взгляд, однако я боюсь, что этот процесс обновления может занять слишком много времени ... Я считаю, чтопромежуточная таблица, которая преобразует широкую таблицу индексов в длинную таблицу, например:

index_id | date_from_column | index_value |

, таким образом, было бы проще объединить таблицы, однако мне потребуется после обновления таблицы индексов TRUNCATE длинная таблица и выполнить 180 INSERT, например:

INSERT INTO long_table SELECT index_id, 'Mar2009' AS date_from_column, Mar2009 AS index_value FROM indexes_table

, где каждый следующий INSERT будет иметь индексы формы имени следующего столбца

1 Ответ

3 голосов
/ 13 февраля 2011

По сути, проблема, с которой вы столкнулись, заключается в том, что ваш дизайн не нормализован и, как следствие, запросы на извлечение информации более сложны.В частности, первая таблица должна быть структурирована следующим образом:

Create Table MonthlyIndexes As
    (
    index_id int not null
    , date datetime not null
    , value ...
    , Primary Key ( index_id, date )
    , Constraint CK_MonthlyIndexes_Date Check ( DatePart(d, date) = 1 )
    )
index_id | date     | value
--------   --------   -------
1        | 20090301 | ...
1        | 20090401 | ...
...

Теперь запрос на получение необходимой информации становится проще:

Select S.saleprice * ( MStart.value / MEnd.value )
From Sales As S
    Join MonthlyIndexes As MStart
        On MStart.date = DateAdd(d, -DatePart(d, S.saledate) + 1)
    Join MonthlyIndexes As MEnd
        On MEnd.date = DateAdd(d, -DatePart(d, CURRENT_TIMESTAMP) + 1)

Запрет реструктуризации вашей схемы,вы можете смоделировать правильный дизайн следующим образом (предположим, что SQL Server 2005 +):

With Indexes As
    (
    Select index_id, Cast('20090301' As datetime) as date, Mar2009
    From MonthlyIndexes
    Union All
    Select index_id, Cast('20090401' As datetime) as date, Apr2009
    From MonthlyIndexes
    ....
    Union All
    Select index_id, Cast('20100201' As datetime) as date, Feb2010
    From MonthlyIndexes
    )
Select S.saleprice * ( MStart.value / MEnd.value )
From Sales As S
    Join MonthlyIndexes As MStart
        On MStart.date = DateAdd(d, -DatePart(d, S.saledate) + 1)
    Join MonthlyIndexes As MEnd
        On MEnd.date = DateAdd(d, -DatePart(d, CURRENT_TIMESTAMP) + 1)

Если таблица месячных индексов велика, вы можете выполнить периодические обновления нормализованной таблицы и использовать ее для своего запроса.1011 *

Другое решение состоит в том, чтобы периодически обновлять промежуточную таблицу с правильно структурированными данными, используя запрос, похожий на запрос Union All в моем CTE.Если данные добавляются один раз в месяц, вы можете даже добавить расписание, хранимое процедурой, которое проверяет, существует ли столбец для данного месяца, и добавляет данные этого месяца.Это будет включать в себя динамический SQL, который я обычно рекомендую использовать, однако для решения по техническому обслуживанию это может решить проблему (пока вы не убедите руководство исправить схему).

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