Я работаю над интеграцией некоторых данных из сторонней системы в одно из моих приложений (устаревшее веб-приложение на базе ASP Classic / SQL 2000) - они приняли некоторые неверные решения (IMHO), когда дело доходит до их подхода и структура данных, хотя, возможно, в какой-то момент у нас будет шанс провести рефакторинг ... но до тех пор я должен работать с тем, что передо мной.
Основная таблица содержит данные проверки, при этом одно из полей используется для записи, если были соблюдены определенные характеристики. Характеристики хранятся в таблице с именем Categories
, но, к сожалению, главная контрольная таблица (Test
) связывается с категориями, объединяя соответствующие CategoryID
s в одно поле (SelectedCategories
). Так, например, если бы наблюдались признаки 01 и 02, столбец SelectedCategories
для этой строки в Test
имел бы значение '01C02C'.
Уравновешенный DDL:
CREATE TABLE [dbo].[Test](
[ItemID] [varchar](255) NOT NULL,
[Result] [varchar](255) NULL,
[Comments] [varchar](255) NULL,
[ResultReason] [varchar](255) NULL,
[ImageLocation] [varchar](255) NULL,
[TestDateTime] [smalldatetime] NOT NULL,
[SelectedCategories] [varchar](255) NULL)
Вопрос, учитывая ситуацию, как лучше всего соответствующим образом извлечь данные из Test
с разбивкой наблюдаемых характеристик?
Выходные данные на клиенте, который я хочу, представляют собой таблицу со следующими столбцами:
Test.PK, Test.Field2 ... Test.Fieldn, Categories.ID1, Categories.ID2, Categories.IDn
Это, вероятно, не совсем ясно - первые поля будут обычными подозреваемыми из Test
, за которыми следует галочка или крестик (или какой-либо другой визуальный индикатор) для каждой из категорий в Categories
.
Очевидно, что если этого можно достичь одним запросом, тем лучше с точки зрения эффективности и производительности. Однако я не уверен, как этого достичь - как бы вы присоединились к таблице Categories
через SelectedCategories
?
Я, очевидно, мог бы просто сообщить значение SelectedCategories
и заставить приложение проанализировать значение. Это может быть жестко запрограммировано или более вероятно, что мы повторно запросим Categories
для каждой строки в Test - хотя это может повлиять на производительность. TBH, производительность, вероятно, не проблема в этом случае, но только потому, что вы можете сойти с рук с чем-то, не означает, что вы должны привыкнуть к этому.
Точно так же, если бы у меня была возможность реорганизовать стороннее приложение, я бы удалил столбец SelectedCategories
и добавил бы в таблицу TestCategories
? Или я бы жестко закодировал каждую категорию как ряд битовых столбцов. По всей вероятности, Categories
не будет меняться в течение всего срока службы системы, но если они это сделали, это означает изменения (хотя и очень незначительные) как для БД, так и для приложения.
Надеюсь, я объяснил это достаточно четко. По сути, я говорю, каков наилучший подход, если я придерживаюсь текущей системы? И если бы мне пришлось провести рефакторинг, какой другой подход я бы выбрал?
Обновление прогресса:
Во многом благодаря Ливену, я до сих пор получил:
DML:
SELECT c.ID, c.Category, t.FilterID, t.OperatorResult, t.SelectedCategories
FROM dbo.Categories c
inner JOIN dbo.Test t ON CHARINDEX(Cast(c.ID as varchar), t.SelectedCategories, 1) <> 0
order by FilterID, ID
Выход:
ID Category FilterID OperatorResult SelectedCategories
4 Cracked Ceramic 137667 FAILED 04C
4 Cracked Ceramic 284821 FAILED 04C
4 Cracked Ceramic 287617 FAILED 04C05C
5 Damaged Case 287617 FAILED 04C05C
4 Cracked Ceramic 310112 FAILED 04C05C
5 Damaged Case 310112 FAILED 04C05C
Этого будет достаточно, за исключением того, что для достижения желаемого результата на экране ...
Filter ID Operator Result Cat Matl Crack Damage High Soot
137667 FAILED X X
178643 FAILED
284821 FAILED X
287617 FAILED X X
310112 FAILED X X
... Мне нужно либо продолжить работу с SQL (чтобы я мог получить желаемый результат всего одним запросом), либо мне нужно проделать дополнительную работу в самом приложении.
Вывод:
Если мы посмотрим на последний пример Ливена (ниже), то увидим, что проблему можно решить с помощью TSQL, но что категории жестко закодированы.
Альтернатива - придерживаться необработанных данных и заставить IIS / ASP выполнять больше работы. Это наверняка усложнит исходный код, но удалит потенциальные издержки обновления TSQL, если категория будет добавлена или удалена. Я, конечно, мог бы справиться с этой очень редкой потребностью в обновлении TSQL, но я обдумываю другие проблемы, когда таблица категорий будет активно меняться на регулярной основе.