如果在SELECT Query中首先匹配,如何跳过其他OR条件?

I am having a trouble with OR condition inside the SELECT.

I want a simple result if one condition is matched and rest OR condition should not be use.

What i want is:

I have some users shared records and i would like to email them the newest items shared on my website.

For me: Newest Items will be least two days older

Like Today is 9th so i would like to pull all records of 7th. but if i didn't get any record of 7th then i would like to pull all record of 6th (3 days older from today). if i didn't get any records on 6th then i would like to pull 1 day older from today.

for all this i have used OR in my SELECT query like this:

SELECT `tg`.* FROM `tblgallery` AS `tg` WHERE (
(tg.added_date BETWEEN '2014-07-07 00:00:00' AND '2014-07-08 00:00:00') OR 
(tg.added_date BETWEEN '2014-07-06 00:00:00' AND '2014-07-07 00:00:00') OR 
(tg.added_date BETWEEN '2014-07-08 00:00:00' AND '2014-07-09 00:00:00') )

And i have records in my database for dates:

2014-07-06
2014-07-07

and when i run this query it gives me all record of both dates.

But I need to pull only record of 2014-07-07 not of both.(I have mentioned above.)

I know i can do this by using multiple Select and i think that will not be a good idea to request to database again and again.

My Question is : How to pull data from database if the first match is true? and skip all data of rest dates?

OR

Is there any other way to do this?

Please Help

Usually one would just work with LIMIT, which is not applicable here, since there might be many rows per day. What I do is quite similar to LIMIT.

SELECT * FROM (
   SELECT
   tg.*,
   @gn := IF(DATE(tg.added_date) != @prev_date, @gn + 1, @gn) AS my_group_number,
   @prev_date := DATE(tg.added_date)
   FROM tblgallery tg
   , (SELECT @gn := 0, @prev_date := CURDATE()) var_init
   ORDER BY FIELD(DATE(tg.added_date), CURDATE() - INTERVAL 1 DAY, CURDATE() - INTERVAL 3 DAY, CURDATE() - INTERVAL 2 DAY) DESC
) sq
WHERE my_group_number = 1;

Here's how it works.

With this line

   , (SELECT @gn := 0, @prev_date := CURDATE()) var_init

the variables are initialized.

Then the ORDER BY is important! The FIELD() function sorts the rows from 2 days ago (gets value 3), to 3 days ago (gets value 2), to 1 day ago (gets value 1). Everything else gets value 0.

Then in the SELECT clause the order is also important.

With this line

   @gn := IF(DATE(tg.added_date) != @prev_date, @gn + 1, @gn) AS my_group_number,

the variable @gn is incremented when the date of the current row is different from the date of the previous row.

With this line

   @prev_date := DATE(tg.added_date)

the date of the current row is assigned to the variable @prev_date. In the line above it still has the value of the previous row.

Now those entries have a 1 in column my_group_number that have the most recent date in the order

2 days ago
3 days ago
yesterday
4 days ago
5 days ago
...

Try this Query:

SELECT GalleryID, PixName, A.added_date
FROM tblGallery A
INNER JOIN (
  SELECT added_date FROM tblGallery
  WHERE added_date <= DATE_SUB('2014-07-09 00:00:00', interval 2 day) 
  GROUP BY added_date
  ORDER BY added_date DESC
  LIMIT 1 ) B
ON A.added_date = B.added_date

See my SQL Fiddle Demo

And even if the date is more than 2 days older it will still work. See here the Demo below wherein the latest is 4 days older from July 9, 2014

See the 2nd Demo

And if you want the current date instead of literal date like here then you could use CURDATE() function instead. Like one below:

SELECT GalleryID, PixName, A.added_date
FROM tblGallery A
INNER JOIN (
 SELECT added_date FROM tblGallery
 WHERE added_date <= DATE_SUB(CURDATE(), interval 2 day) 
 GROUP BY added_date
 ORDER BY added_date DESC
 LIMIT 1 ) B
ON A.added_date = B.added_date

See 3rd Demo

Well, I'm not being able to solve the multi OR issue but this is how could you get records being added last two days. Change the interval or the CURDATE() in order to fit your needs.

SELECT id, date_added
FROM gallery
WHERE date_added BETWEEN CURDATE() - INTERVAL 2 DAY AND CURDATE()
ORDER BY date_added

Check the SQL Fiddel

It is not about how OR works in MySQL. I think you are misunderstanding where part by looking at your discussion with @B.T. It will be executed for each record. so if one of the record evaluates to false for the first condition then it will evaluate the second condition for that particular record and so on so if any condition evaluates to true by considering all the conditions then that will become part of your result set.

Try this query.

SELECT `tg`.* FROM `tblgallery` AS `tg` WHERE tg.added_date = (
select date (
select distinct(tg.added_date) date from tblgallery as tg
) as t1 order by case  
                    when date between '2014-07-07 00:00:00' AND '2014-07-08 00:00:00'
                        then 1
                    when date between '2014-07-06 00:00:00' AND '2014-07-07 00:00:00'
                        then 2
                    when date between '2014-07-08 00:00:00' AND '2014-07-09 00:00:00'
                        then 3
                    else 4
                end limit 1);

Here's what I am doing in this query.

  • I am getting all the distinct dates.
  • then I am ordering all the condition in order i.e if first condition is true then 1, if second is true then 2 and so on.
  • I am limiting the result to 1 so after the order whichever the result is the first row will be selected and which is a date and will be used in the condition.

Note: I have note tested it yes, so you may need to do some changes to the query.