Я побеждал голову на столе, пытающемся понимать этого. У меня есть таблица, которая хранит информацию задания и рассуждает для задания, не завершаемого. Причины являются числовыми, 01,02,03, и т.д. У Вас может быть две причины незаконченного задания. Если Вы выбираете две причины, они хранятся в том же столбце, разделенном запятой. Это - пример от таблицы JOBID:
Job_Number User_Assigned PendingInfo
1 user1 01,02
Существует названное Ожидание другой таблицы, которое хранит то, что на самом деле представляют те значения. 01=Not достаточно информации, 02=Not достаточно времени, 03=Waiting Обзор. Пример:
Pending_Num PendingWord
01 Not Enough Info
02 Not Enough Time
То, что я пытаюсь сделать, запросить базу данных, чтобы дать мне все числа задания, пользователей, pendinginfo, и незаконченную причину. Я могу вспыхнуть первое значение, но не могу выяснить, как сделать второе. Что мои ограниченные навыки имеют до сих пор:
select Job_number,user_assigned,SUBSTRING(pendinginfo,0,3),pendingword
from jobid,pending
where
SUBSTRING(pendinginfo,0,3)=pending.pending_num and
pendinginfo!='00,00' and
pendinginfo!='NULL'
То, что я хотел бы видеть этот пример, будет:
Job_Number User_Assigned PendingInfo PendingWord PendingInfo PendingWord
1 User1 01 Not Enough Info 02 Not Enough Time
Заранее спасибо
Надеюсь, вы просто поддерживаете код, и это не совершенно новая реализация.
Пожалуйста, рассмотрите возможность использования другого подхода, используя вспомогательную таблицу, такую как эта:
JOBS TABLE
jobID | userID
--------------
1 | user13
2 | user32
3 | user44
--------------
PENDING TABLE
pendingID | pendingText
---------------------------
01 | Not Enough Info
02 | Not Enough Time
---------------------------
JOB_PENDING TABLE
jobID | pendingID
-----------------
1 | 01
1 | 02
2 | 01
3 | 03
3 | 01
-----------------
Вы можете легко запросить эти таблицы с помощью JOIN или подзапросов.
Если вам нужна ретро-совместимость в вашем ПО, вы можете добавить представление для достижения этой цели.
Вы действительно не должны хранить несколько элементов в одном столбце, если ваш SQL когда-либо захочет обрабатывать их по отдельности. «Гимнастика SQL», которую вы должны выполнять в этих случаях, является одновременно уродливым взломом и ухудшает производительность.
Идеальное решение - разделить отдельные элементы на отдельные столбцы и для 3NF переместить эти столбцы в отдельную таблицу в виде строк, если вы действительно хотите сделать это правильно (но маленькие шаги, вероятно, подходят если вы уверены, что в краткосрочной перспективе никогда не будет больше двух причин).
Тогда ваши запросы будут проще и быстрее.
Однако, если это не вариант, вы можете использовать вышеупомянутую гимнастику SQL, чтобы сделать что-то вроде:
where find ( ',' |fld| ',', ',02,' ) > 0
предполагая, что ваш диалект SQL имеет функцию поиска строки (в данном случае find
, но Я думаю charindex
для SQLServer).
Это обеспечит начало и начало всех подстолбцов с запятой (запятая плюс поле плюс запятая) и поиск определенного желаемого значения (с запятыми с обеих сторон, чтобы гарантировать полное соответствие подстолбца).
Если вы не можете контролировать, что приложение помещает в этот столбец, я бы выбрал решение DBA - решения DBA определяются как те, которые администратор баз данных должен делать, чтобы обойти недостатки своих пользователей. :-).
Создайте два новых столбца в этой таблице и сделайте триггер вставки / обновления, который заполнит их двумя причинами, которые пользователь помещает в исходный столбец.
Затем запросите в этих двух новых столбцах конкретные значения, а не пытайтесь разделить старый столбец.
Это означает, что затраты на разбиение связаны только с вставкой / обновлением строки, а не с каждым отдельным выбором, что эффективно снижает затраты.
Тем не менее, мой ответ - переделать схему. В долгосрочной перспективе это будет лучший способ с точки зрения скорости, удобочитаемости запросов и удобства обслуживания.
Если изменение схемы является вариантом (что, вероятно, должно быть), не следует ли вам реализовать здесь отношение «многие ко многим», чтобы у вас была таблица мостов между двумя элементами? Таким образом, вы сохраните номер и его формулировку в одной таблице, задания в другой, а «причины сбоев для заданий» в таблице моста ...
Посмотрите на аналогичный вопрос, на который я ответил здесь
;WITH Numbers AS
(
SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 0)) AS N
FROM JobId
),
Split AS
(
SELECT JOB_NUMBER, USER_ASSIGNED, SUBSTRING(PENDING_INFO, Numbers.N, CHARINDEX(',', PENDING_INFO + ',', Numbers.N) - Numbers.N) AS PENDING_NUM
FROM JobId
JOIN Numbers ON Numbers.N <= DATALENGTH(PENDING_INFO) + 1
AND SUBSTRING(',' + PENDING_INFO, Numbers.N, 1) = ','
)
SELECT *
FROM Split JOIN Pending ON Split.PENDING_NUM = Pending.PENDING_NUM
Основная идея состоит в том, что вам нужно умножить каждую строку столько раз, сколько есть PENDING_NUM
с. Затем извлеките соответствующую часть строки