简体   繁体   中英

mysql query returning wrong results

Background...

I'm trying to query the database to see what rental properties we have available in a given date range. The storage method is horrible, but it's being created by a desktop program :/ The website is written in Wordpress, but I can't even get the correct results even when I manually query the database.

The Problem... There are 3 columns in the database: propid , av_date and avail . I have a property that is booked on May 31st and June 8th, but available every day between. When I view the data in the table, it looks like this:

propid   av_date     avail

1051     2013-05-31  U
1051     2013-06-01  A
1051     2013-06-02  A
1051     2013-06-03  A
1051     2013-06-04  A
1051     2013-06-05  A
1051     2013-06-06  A
1051     2013-06-07  A
1051     2013-06-08  U

When I run the following query, the property is still showing up...

SELECT DISTINCT propid
FROM availabilities
WHERE avail = 'A'
AND av_date IN ('2013-05-31', '2013-06-01', '2013-06-02', '2013-06-03', '2013-06-04', '2013-06-05', '2013-06-06', '2013-06-07', '2013-06-08');

I've been beating my head against the wall for 2 days over this, so it's probably something stupid, but any help would be greatly appreciated!

If you want to exclude the property entirely if it has an avail = 'U' in the date range, try counting for occurrences of U and omitting any that have at least one U :

SELECT propid
FROM availabilities
WHERE av_date IN ('2013-05-31', '2013-06-01', '2013-06-02', '2013-06-03', '2013-06-04', '2013-06-05', '2013-06-06', '2013-06-07', '2013-06-08')
GROUP BY propid
HAVING COUNT(CASE WHEN avail = 'U' THEN 1 END) = 0

And finally, you can use a range for the dates with BETWEEN , which makes the query shorter and easier to maintain:

SELECT propid
FROM availabilities
WHERE av_date BETWEEN '2013-05-31' AND '2013-06-08'
GROUP BY propid
HAVING COUNT(CASE WHEN avail = 'U' THEN 1 END) = 0

try:

SELECT propid, avail, av_date
FROM availabilities
GROUP BY propid HAVING avail = 'A'
AND av_date IN ('2013-05-31', '2013-06-01', '2013-06-02', '2013-06-03', '2013-06-04', '2013-06-05', '2013-06-06', '2013-06-07', '2013-06-08');

You can exclude propids with any unavailability by using NOT EXISTS:

SELECT DISTINCT a.propid 
FROM availabilities a
WHERE NOT EXISTS
( SELECT 1
FROM availabilities b
WHERE b.avail = 'U' 
AND b.propid = a.propid 
AND b.av_date IN ('2013-05-31', '2013-06-01', '2013-06-02', '2013-06-03', '2013-06-04', '2013-06-05', '2013-06-06', '2013-06-07', '2013-06-08');
)

The subquery can include conditions based on values from availabilities a.

Your query is finding properties that are available on any of the dates. To get all the dates, you have a set-within-sets question. I find the best approach is aggregation with a having clause.

SELECT propid
FROM availabilities
group by propid
having sum(case when av_date IN ('2013-05-31', '2013-06-01', '2013-06-02', '2013-06-03', '2013-06-04', '2013-06-05', '2013-06-06', '2013-06-07', '2013-06-08') and
                     avail <> 'A'
                then 1
                else 0
           end) > 0

The having clause counts the number of rows where the condition is not true. If there are any, then the property is not included. You can also approach this as:

SELECT propid
FROM availabilities
group by propid
having sum(case when av_date IN ('2013-05-31', '2013-06-01', '2013-06-02', '2013-06-03', '2013-06-04', '2013-06-05', '2013-06-06', '2013-06-07', '2013-06-08') and
                     avail = 'A'
                then 1
                else 0
           end) = 9;

The 9 is the number of dates in your set.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM