2015-10-25 2 views
-2

Я просто не могу найти решение для этого запроса хранимой процедуры.Сохраненная процедура - проблемы с запросом

У меня есть Person и a Student стол. В таблице Person я храню значение bool isFootballPlayer и Student таблица имеет FK PersonId, которая ссылается на таблицу Person.

У меня есть веб-приложение, где есть функция поиска, которая включает флажок для Студента, Лица и Футболиста, чтобы отфильтровать результаты. Поэтому, когда выбрано только Лицо, оно вернет все, что не Игроков и учеников.

Моя хранимая процедура выглядит следующим образом:

"SP stuff" 
@IncludePerson bit, 
@IncludePlayer bit, 
@IncludeStudent bit 
AS 
BEGIN 
    WITH i (Id) 
    SELECT 
     p.PersonId as Id 
    FROM 
     Person p 
    LEFT OUTER JOIN 
     Student s ON s.PersonId = p.PersonId 
    WHERE 
     (s.PersonId IS NULL OR @IncludeStudent = 1) AND 
     (p.IsFootballPlayer = 0 OR @IncludePlayer = 1) AND 
     ((s.PersonId > 0) OR @IncludePerson = 1) 
    ) 
    SELECT i.Id 
    FROM i 
    GROUP BY i.Id 
END 

Проблема здесь в том, что некоторые студенты также могут быть футболисты, и поэтому, когда только студент флажок установлен, то результат исключает студентов, которые также футболистов, если оба флажка не установлены.

Может ли кто-нибудь помочь мне в правильном направлении и дать мне несколько советов о том, как я могу изменить хранимую процедуру, чтобы показать студентам, которые также являются футболистами, без необходимости проверять оба флажка?

Благодаря

+0

Можете ли вы объяснить немного больше, что хотите ли вы вернуться к каждой комбинации флажков? это неясно, что вы ожидаете, когда проверяется только футболист или когда флажок человека не проверяется вообще. или когда проверяется более одного флажка, как студенты и футболисты. –

+0

Извините, что вы не очень точны. Ну, я ожидаю, что когда будет выбран только один флажок, результат будет только футболистом, человеком или учеником! Если все выбрано, это, естественно, вернет всех. Когда выбираются человек и студент f.ex, я хочу, чтобы футболисты были исключены, и то же самое было бы для любой другой комбинации; что неконтролируемый результат не закончится! Насколько я понимаю, ваш запрос будет работать, только если выбран флажок! –

ответ

0
"SP stuff" 
@IncludePerson bit, 
@IncludePlayer bit, 
@IncludeStudent bit 
AS 
BEGIN 
    Declare @Sql NVARCHAR(MAX); 

SET @Sql = N'SELECT DISTINCT p.PersonId as Id 
      FROM Person p 
      WHERE 1 = 1 ' 

      -- When only Person checkbox is checked 
      + CASE WHEN (@IncludePerson = 1 AND @IncludeStudent = 0 AND @IncludePlayer = 0) 
      THEN N' AND p.IsFootballPlayer = 0 
        AND NOT EXISTS (SELECT 1 FROM Student s 
            WHERE s.PersonId = p.PersonId)' ELSE N'' END 
      -- When only Student checkbox is checked 
      + CASE WHEN (@IncludePerson = 0 AND @IncludeStudent = 1 AND @IncludePlayer = 0) 
      THEN N' AND EXISTS (SELECT 1 FROM Student s 
           WHERE s.PersonId = p.PersonId)' ELSE N'' END 
      -- When only Player checkbox is checked 
      + CASE WHEN (@IncludePerson = 0 AND @IncludeStudent = 0 AND @IncludePlayer = 1) 
      THEN N' AND p.IsFootballPlayer = 1 ' ELSE N'' END 
      -- And you can add as many as combinations you want 

-- Finally execute the dynamically built sql query 

    Exec sp_executesql @Sql 

END 
+0

Жаль, что вы не очень точны. Ну, я ожидаю, что когда будет выбран только один флажок, результат будет только футболистом, человеком или учеником! Если все выбрано, это, естественно, вернет всех. Когда выбираются человек и студент f.ex, я хочу, чтобы футболисты были исключены, и то же самое было бы для любой другой комбинации; что неконтролируемый результат не закончится! Насколько я понимаю, ваш запрос будет работать, только если выбран флажок! –

0

Почему вы не установите переменную @IncludePlayervalue = 1 внутри хранимой процедуры при @IncludeStudent = 1, как указано ниже -

"SP stuff" 
@IncludePerson bit, 
@IncludePlayer bit, 
@IncludeStudent bit 
AS 
BEGIN 
if @IncludeStudent = 1 
    begin 
    set @IncludePlayer = 1 
    end 
    WITH i (Id) 
    SELECT 
     p.PersonId as Id 
    FROM 
     Person p 
    LEFT OUTER JOIN 
     Student s ON s.PersonId = p.PersonId 
    WHERE 
     (s.PersonId IS NULL OR @IncludeStudent = 1) AND 
     (p.IsFootballPlayer = 0 OR @IncludePlayer = 1) AND 
     ((s.PersonId > 0) OR @IncludePerson = 1) 
    ) 
    SELECT i.Id 
    FROM i 
    GROUP BY i.Id 
END 
+0

Привет ** sam ** и спасибо за ваш комментарий! Наверное, я немного поспешил написать мой предыдущий комментарий о том, какие результаты я ожидаю, поэтому я действительно надеюсь, что мне удастся сделать это хорошо на этот раз. Дело в том, что, поскольку 'isFootballPlayer' является частью' Person', а не отдельной таблицей, такой как 'Student', когда выбран только один флажок (скажем, игроки), естественно, будут _person_ или _students_, которые также являются _players_. Поэтому в этом случае я также ожидаю, что ученики/человек, но кто также является игроком, появятся! –

Смежные вопросы