У меня есть большая таблица формул тегов, таблица числовых данных в базе данных SQL Server 2008. Таблица формул похожа на
ID INT PRIMARY KEY,
Formula VARCHAR(MAX), -- Nullable.
Правила:
- Каждый тег имеет запись в таблице формул
- Если формула не равна нулю, это означает, что в таблице данных нет значения
- Если формула пуста, это означает, что значение данных поступает из таблицы данных. В этом случае я называю это тегом 'value'.
- В случае 2 Формула может быть чем-то вроде T (123) + T (456), но никогда не будет как T (T (234) + T (456)). Идентификационная часть в T (ID) должна быть постоянным числом. Формула может быть + - * / () и может иметь некоторые функции SQL.
Таблица данных похожа на
DATE SMALLDATETIME PRIMARY KEY, -- 2019-06-01
ID INT PRIMARY KEY, -- Which ID this value belongs to
VALUE FLOAT -- Not Nullable
Правила таблицы данных
- Не все теги значений имеют свои записи в таблице данных на основе даты.
- ДАТА и ID являются первичными ключами
Итак, я написал func ExtractTags, взял varchar (max) и вернул 2 значения необработанных тегов и извлеченную формулу.
* 1 028 * Пример:
Введите:
'T(234) As T234, T(567) As T567'
Выход:
RawTag:
'[1],[3],[2],[6],[8],[10],[13],[467]'
ExtractedTags:
'(([1] + [2]) * ([3] + [6]) - [8]) As T234, ([10] + [13] + [467]) As T567'
Динамический SQL, который я сгенерировал, будет выглядеть как
SELECT DATE, (([1] + [2]) * ([3] + [6]) - [8]) As T234, ([10] + [13] + [467]) As T567
FROM (SELECT N.DATE, N.Value, N.ID
FROM NumericData AS N
Where N.DATE BETWEEN '2019-05-01' And '2019-05-3'
)
x PIVOT (
MAX(Value) for ID in ([1],[3],[2],[6],[8],[10],[13],[467])
) p
Затем, основываясь на этом значении 2, я могу создать динамический SQL, который будет вращаться относительно таблицы данных, а затем получит значение и вычислит результат.
Проблема:
- Поскольку некоторые значения могут не иметь записи на определенную дату, поэтому может отображаться значение Null. например, ([10] + [13] + [467]) ==> T567. если [467] не имеет значения, то результат равен нулю. В этом случае я хочу игнорировать значение [467] или считать его 0.
- Если я поменяю все [xxx] на IsNull ([xxx], 0), возникнет еще одна проблема: скажем, [10], [13] и [467] равны нулю, тогда я хочу видеть T567 как ноль .
- Я думаю создать свою собственную функцию. SUMIFNOTNULL (a, b) ==> Возвращает ноль, только если a и b равны нулю, в противном случае ноль равен 0.
- Но проблема в том, что я не могу изменить таблицу формул, и
это может продолжать расти. б) Даже если я смогу, это будет огромная работа, чтобы изменить
все формулы (более 10000 записей)
Пример вывода
Если я использую IsNull ([xxx], 0), я увижу
DATE | T234 | T567
----------+---------+---------
2019-05-01| 0 | 0
2019-05-02| 123.5 | 0
2019-05-03| 456.5 | 567.5
Если я не использую IsNull ([xxx], 0), я увижу
DATE | T234 | T567
----------+---------+---------
2019-05-01| NULL | NULL
2019-05-02| 123.5 | NULL
2019-05-03| 456.5 | 567.5
Я очень хочу увидеть
DATE | T234 | T567
----------+---------+---------
2019-05-01| 0 | NULL
2019-05-02| 123.5 | 0
2019-05-03| 456.5 | 567.5
Любая хорошая идея, чтобы решить эту проблему? Может ли SQL Server переопределить оператор '+'?