Как получить правильные значения из нескольких операторов where в SQL Server - PullRequest
0 голосов
/ 26 декабря 2018

У меня есть поисковая система, в которой пользователь задает несколько условий, и на основании этих условий я возвращаю таблицу данных.

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

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

USE [Tenant Management]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[RentSearchEngine]
    @sqm INT,
    @category INT,
    @shortRentPrice MONEY,
    @longRentPrice MONEY,
    @fromDate DATETIME,
    @toDate DATETIME
AS
BEGIN
    SET NOCOUNT ON;

    SELECT 
        c.[Name], cate.[Channel Category], tp.type, st.Status, c.Surface,
        g.GOVERNATOR + ' ' + d.District + ' ' + cit.City + ' ' as [Address],
        c.[Short term Price per night] AS [Short term monthly amount],
        c.[Long term price per month] AS [Long term monthly amount],
        c.[Selling Price]
    FROM
        [dbo].[Channel] c
    INNER JOIN 
        [dbo].[Governator] g ON c.[Governator ID] = g.ID
    INNER JOIN 
        [dbo].[District] d ON c.[District ID] = d.ID
    INNER JOIN 
        [dbo].[City] cit ON c.[City ID] = cit.id
    INNER JOIN
        [dbo].[Channel_Category] cate ON c.[Channel Category ID] = cate.ID
    INNER JOIN
        [dbo].[Channel_Type] tp ON c.[Channel Type] = tp.id
    INNER JOIN
        [dbo].[Channel_Status] st ON c.[Channel Status] = st.ID
    LEFT JOIN
        [dbo].[Reservations] r ON c.[ID] = r.[Channel ID]
    WHERE 
        c.[Channel Status] = '5'
        AND c.[Channel Type] = '1'
        AND c.[Channel Category ID] = @category OR @category IS NULL
        AND c.Surface BETWEEN @sqm * 0.85 AND @sqm * 1.15 OR @sqm IS NULL
        AND c.[Long term price per month] BETWEEN @longRentPrice * 0.85 
                                              AND @longRentPrice * 1.15 OR @longRentPrice IS NULL
        AND c.[Short term Price per night] BETWEEN @shortRentPrice * 0.85 
                                               AND @shortRentPrice * 1.15 OR @shortRentPrice IS NULL
        AND (r.[Actual Date in] > @fromDate AND r.[Actual Date out] > @toDate)
        AND (r.[Actual Date in] < @fromDate AND r.[Actual Date out] < @toDate)
END

Текущий результат:

  fdfd  Residential apatment    For Rent    Available   500  Mont Liban  Baabda  Ain El Remmaneh    1287182.00  28712.00    128712.00

При выполнении хранимой процедуры следующим образом:

 DECLARE    @return_value int
 EXEC   @return_value = [dbo].[RentSearchEngine]
    @sqm = 40000,
    @category = 1,
    @shortRentPrice = 5,
    @longRentPrice = 4,
    @fromDate = NULL,
    @toDate = NULL
SELECT  'Return Value' = @return_value

1 Ответ

0 голосов
/ 26 декабря 2018

Я думаю, что ключевым вопросом является предпочтение оператора для AND & OR.Имейте в виду, что AND имеет более высокое предпочтение, чем OR.В этих сложных условиях хорошей практикой является обеспечение порядка с круглыми скобками.Я напишу то, что, как я понимаю, вы пытаетесь достичь, но убедитесь, что вы используете круглые скобки в порядке, который вам необходим:

where c.[Channel Status] = '5'
                and c.[Channel Type] = '1'
                and (c.[Channel Category ID] =@category or @category IS NULL)
                and (c.Surface between @sqm*0.85 and @sqm*1.15 or @sqm IS NULL)
                and (c.[Long term price per month] between @longRentPrice*0.85 and @longRentPrice*1.15 or @longRentPrice IS NULL)
                and (c.[Short term Price per night] between @shortRentPrice*0.85 and @shortRentPrice*1.15 or @shortRentPrice IS NULL)
                and (r.[Actual Date in] > @fromDate and r.[Actual Date out] > @toDate)
                and (r.[Actual Date in] < @fromDate and r.[Actual Date out] < @toDate)
...