«Совпадение большинства столбцов» очень расплывчато, но я предполагаю, что вы имеете в виду, что если они ищут ноль или если значение в таблице равно нулю, то предположим, что эта запись может быть включена.
Если вам нужна наиболее подходящая строка или все строки, которые ничего не соответствуют, то вам нужно будет сделать что-то вроде этого (оно начинает становиться очень длинным)
DECLARE @Client_Id VARCHAR(MAX) = '500'
DECLARE @Project_ID VARCHAR(MAX) = '2'
DECLARE @Phase VARCHAR(MAX) = NULL
DECLARE @Task VARCHAR(MAX) = NULL
SELECT Employee, Sequence
FROM
(SELECT Employee, Sequence,
(
CASE WHEN (Client_Id = @Client_Id OR Client_Id IS NULL OR @Client_Id IS NULL) THEN 1 ELSE 0 END +
CASE WHEN (Project_ID = @Project_ID OR Project_ID IS NULL OR @Project_ID IS NULL) THEN 1 ELSE 0 END +
CASE WHEN (Phase = @Phase OR Phase IS NULL OR @Phase IS NULL) THEN 1 ELSE 0 END +
CASE WHEN (Task = @Task OR Task IS NULL OR @Task IS NULL) THEN 1 ELSE 0 END
) AS MatchCount
WHERE MatchCount =
(
SELECT MAX(
CASE WHEN (Client_Id = @Client_Id OR Client_Id IS NULL OR @Client_Id IS NULL) THEN 1 ELSE 0 END +
CASE WHEN (Project_ID = @Project_ID OR Project_ID IS NULL OR @Project_ID IS NULL) THEN 1 ELSE 0 END +
CASE WHEN (Phase = @Phase OR Phase IS NULL OR @Phase IS NULL) THEN 1 ELSE 0 END +
CASE WHEN (Task = @Task OR Task IS NULL OR @Task IS NULL) THEN 1 ELSE 0 END
)
FROM myTable
)
-- Now prevent for duplicate sequence numbers
AND NOT EXISTS (
SELECT Employee, Sequence
FROM
(SELECT Employee, Sequence,
(
CASE WHEN (Client_Id = @Client_Id OR Client_Id IS NULL OR @Client_Id IS NULL) THEN 1 ELSE 0 END +
CASE WHEN (Project_ID = @Project_ID OR Project_ID IS NULL OR @Project_ID IS NULL) THEN 1 ELSE 0 END +
CASE WHEN (Phase = @Phase OR Phase IS NULL OR @Phase IS NULL) THEN 1 ELSE 0 END +
CASE WHEN (Task = @Task OR Task IS NULL OR @Task IS NULL) THEN 1 ELSE 0 END
) AS MatchCount
FROM myTable) mt2
WHERE mt2.MatchCount =
(
SELECT MAX(
CASE WHEN (Client_Id = @Client_Id OR Client_Id IS NULL OR @Client_Id IS NULL) THEN 1 ELSE 0 END +
CASE WHEN (Project_ID = @Project_ID OR Project_ID IS NULL OR @Project_ID IS NULL) THEN 1 ELSE 0 END +
CASE WHEN (Phase = @Phase OR Phase IS NULL OR @Phase IS NULL) THEN 1 ELSE 0 END +
CASE WHEN (Task = @Task OR Task IS NULL OR @Task IS NULL) THEN 1 ELSE 0 END
)
FROM myTable
)
AND mt2.Sequence = myTable.Sequence AND mt2.MatchCount > myTable.MatchCount
)
Примечание: это вернет все записи в таблице, когда количество совпадающих полей равно нулю.
Я уверен, что это способы, которые можно было бы очистить, чтобы они не были настолько многословными, вставляя все соответствующие строки во временную таблицу и включая количество совпадающих столбцов (MatchCount
), уменьшая запрос значительно.
Теперь, так как вы хотите, чтобы уникальные последовательности и строки с наибольшим соответствием были возвращены, искомый результат выглядит примерно так:
DECLARE @Client_Id VARCHAR(MAX) = '500'
DECLARE @Project_ID VARCHAR(MAX) = '3'
DECLARE @Phase VARCHAR(MAX) = NULL
DECLARE @Task VARCHAR(MAX) = NULL
INSERT INTO #myTempTable SELECT Employee, Sequence,
(
CASE WHEN (Client_Id = @Client_Id OR Client_Id IS NULL OR @Client_Id IS NULL) THEN 1 ELSE 0 END +
CASE WHEN (Project_ID = @Project_ID OR Project_ID IS NULL OR @Project_ID IS NULL) THEN 1 ELSE 0 END +
CASE WHEN (Phase = @Phase OR Phase IS NULL OR @Phase IS NULL) THEN 1 ELSE 0 END +
CASE WHEN (Task = @Task OR Task IS NULL OR @Task IS NULL) THEN 1 ELSE 0 END
) AS MatchCount,
(
CASE WHEN (Client_Id IS NULL) THEN 1 ELSE 0 END +
CASE WHEN (Project_ID IS NULL) THEN 1 ELSE 0 END +
CASE WHEN (Phase IS NULL) THEN 1 ELSE 0 END +
CASE WHEN (Task IS NULL) THEN 1 ELSE 0 END
) AS NullCount
-- ,(
-- CASE WHEN (Client_Id = @Client_Id OR @Client_Id IS NULL) THEN 1 ELSE 0 END +
-- CASE WHEN (Project_ID = @Project_ID OR @Project_ID IS NULL) THEN 1 ELSE 0 END +
-- CASE WHEN (Phase = @Phase OR @Phase IS NULL) THEN 1 ELSE 0 END +
-- CASE WHEN (Task = @Task OR @Task IS NULL) THEN 1 ELSE 0 END
-- ) AS MatchCountWithoutNulls
SELECT Employee, Sequence
FROM #myTempTable mtt
WHERE MatchCount = (
SELECT MAX(MatchCount)
FROM #myTempTable mtt2
WHERE mtt2.Sequence = mtt.Sequence
)
AND NullCount = (
SELECT MIN(NullCount)
FROM #myTempTable mtt2
WHERE mtt2.Sequence = mtt.Sequence
)
Или что-то очень близкое к этому, у меня нет тестового стола, поэтому я не могу его пнуть и посмотреть.