SQL возвращает 1 при переключении регистра, когда количество больше 0

#sql #sql-server #stored-procedures

#sql #sql-сервер #хранимые процедуры

Вопрос:

У меня есть входной список int в хранимой процедуре, у каждого идентификатора есть документ, и у каждого документа есть несколько вложенных документов. Подключено subdocument.DocumentId = document.DocumentId .

Что мне нужно сделать, так это вернуть список объектов ( document.DocumentId int, IsValid bool ).

Значение bool равно true, если 2 столбца каждого подключенного вложенного документа не равны нулю.

PARAMLIST: список идентификаторов

 SELECT 
    IDS.ParamList AS documentId,
    CASE 
        WHEN (SELECT COUNT(*) 
              FROM Document D
              JOIN SubDocument SD ON SD.DocumentId = D.DocumentId
              WHERE SD.DocumentId = IDS.ParamList 
                AND SD.PaymentDate IS NULL 
                AND SD.ConnectionContractIsAcceptedDate IS NULL) > 0
             THEN 1
             ELSE 0 
    END AS IsValid
FROM 
    @documentIds IDS
 

Как вы можете видеть, моя логика заключалась в том, чтобы переключить регистр, где я считаю каждый SubDocument , в котором не заполнен хотя бы один из столбцов, но запрос ничего не возвращает, только имена 2 столбцов

Таблица документов:

documentId CreatedBy
1 Джон
2 Джилл

Таблица вложенных документов:

SubDocumentId documentId Поле 1 Поле 2
3 1 NULL 2010-02-02
4 2 2021-01-01 2018-03-03
5 1 2020-10-10 2015-11-15
6 2 2019-10-01 2013-12-12

Здесь ожидаемый результат:

documentId isValid
1 false
2 верно

Комментарии:

1. Почему SELECT COUNT(*) , почему не просто CASE WHEN EXISTS

Ответ №1:

Вы можете присоединить табличную переменную к таблицам.
Затем используйте условную агрегацию для вычисления isValid.

 declare @DocumentIds table (
 DocumentId int
);

insert into @DocumentIds values (1),(2);

SELECT Doc.DocumentId, Doc.CreatedBy
, CAST(MIN(
      CASE
      WHEN (SubDoc.Field1 IS NULL OR SubDoc.Field2 IS NULL) 
      THEN 0
      ELSE 1
      END) AS BIT) AS IsValid
FROM Document Doc
JOIN @DocumentIds Ids 
  ON Ids.DocumentId = Doc.DocumentId
LEFT JOIN SubDocument SubDoc
  ON SubDoc.DocumentId = Doc.DocumentId
GROUP BY Doc.DocumentId, Doc.CreatedBy
ORDER BY Doc.DocumentId;
 
documentId CreatedBy isValid
1 Джон False
2 Джилл Верно

Демонстрация в db<>fiddle здесь