Reputation: 41
Table Schema:
CREATE TABLE [dbo].[Message](
[id] [int] NOT NULL,
[created_on] [datetime] NULL,
[message] [nvarchar](max) NULL,
CONSTRAINT [PK_Message] PRIMARY KEY CLUSTERED
(
[id] ASC
)
) ON [PRIMARY]
Values:
1 '2013-01-01 00:00:00.000' 'error occured "BASKET_BALL"'
2 '2014-01-01 00:00:00.000' 'error occured "FOOT_BALL"'
3 '2012-01-01 00:00:00.000' 'I am not involved in like operator'
4 '2014-02-01 00:00:00.000' 'I might be involved'
Query return against the table:
SELECT
ID,CREATED_ON,MESSAGE
FROM
MESSAGE
WHERE
MESSAGE NOT LIKE '%"FOOT_BALL"%' OR MESSAGE NOT LIKE '%BASKET_BALL%'
AND CREATED_ON >= '2014-01-01'
Output:
1 2013-01-01 00:00:00.000 error occured "BASKET_BALL"
2 2014-01-01 00:00:00.000 error occured "FOOT_BALL"
3 2012-01-01 00:00:00.000 I am not involved in like operator
4 2014-02-01 00:00:00.000 I might be involved
Question:
Could some one explain why the query returns all the table values when explicitly the date condition is mentioned for greater than 2014 ? I understand by keeping the message condition in bracket it yields proper result. However, like to know why the sql excludes date condition mentioned when the not like operator is not in bracket.
Upvotes: 4
Views: 8125
Reputation: 44881
It's because the AND
operator has higher precedence than OR
. Change to this:
SELECT
ID,CREATED_ON,MESSAGE
FROM
MESSAGE
WHERE
(MESSAGE NOT LIKE '%"FOOT_BALL"%' OR MESSAGE NOT LIKE '%BASKET_BALL%')
AND CREATED_ON >= '2014-01-01'
Depending on what you want maybe the parenthesis should surround the latter part, like so:
MESSAGE NOT LIKE '%"FOOT_BALL"%' OR (MESSAGE NOT LIKE '%BASKET_BALL%'
AND CREATED_ON >= '2014-01-01')
Upvotes: 5
Reputation: 26784
You are missing parantheses so OR having lower precedence translates as
WHERE
MESSAGE NOT LIKE '%"FOOT_BALL"%' OR (MESSAGE NOT LIKE '%BASKET_BALL%'
AND CREATED_ON >= '2014-01-01')
MESSAGE NOT LIKE '%"FOOT_BALL"%'
returs 3 rows, doesnt care about the date
Put both ORs in parentheses.
Upvotes: 1