0

I have code for my filter. It worked well until I add new product in my database. I found the problem, but dont know what to do with that.

I have parameters "alc_min" and "alc_max" in my filter. I get these from crawling all products. After I send this filter, I fire this code:

$meta_query = array();
$b = "alc_min";
$c = "alc_max";
if (isset ( $data [$b] ) && isset ( $data [$c] )) {
    $compare = "BETWEEN";
    $a = array (
            'key' => "alc",
            'value' => array (
                    $data [$b],
                    $data [$c]
            ),
            'compare' => $compare
    );
    array_push ( $meta_query, $a );
}

            $items = new WP_Query ( array (
                    'post_type' => $type,
                    'posts_per_page' => $posts_per_page,
                    'order' => $order,
                    'meta_key' => $orderkey,
                    'orderby' => $orderby,
                    'post_status' => 'publish',
                    'meta_query' => $meta_query,
                    'paged' => $paged
            ) );

Until now, it worked well. No I add new product with "alc" <10 and I found, that if I have "alc_min" and "alc_max" <10 or >10, it is ok. But if "alc_min" is <10 and "alc_max" >10 I get no results at all.

Does anyone any idea what to check or fix?

  • So to give real examples: the query would work for 5,9 and 17,18 but not 5,15 (min,max)? – Maroun Melhem Sep 18 '21 at 19:22
  • Yes, thats it. I have this query of real site (e-shop) for couple of months without problem, but nwow I added product with "alc" bellow 10 and I found this problem. – Jaroslav Hor Sep 19 '21 at 03:11
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Sep 25 '21 at 20:41

1 Answers1

1

After the clarification, I've suspected that the reason why selecting "alc_min" = 7 and "alc_max" = 13 doesn't yield any result is because of the column datatype. Consider this example:

CREATE TABLE table1 (
alc VARCHAR(50));

INSERT INTO table1 VALUES 
('7'),
('9'),
('11'),
('13');

The table above is created with alc column datatype as VARCHAR instead of INTEGER (or numeric datatype). I've tested that running either one of the query below:

SELECT * FROM table1 WHERE alc BETWEEN '7' AND '9';
SELECT * FROM table1 WHERE alc BETWEEN '11' AND '13';

will return the expected result. However, with this query:

SELECT * FROM table1 WHERE alc BETWEEN '7' AND '13';

yields no result. This is because the values are treated as string instead of numbers and when that happens, 1 is always smaller than 7. See below what happen you run select query with order by on the data set above:

SELECT * FROM table1 ORDER BY alc;

+-----+
| alc |
+-----+
|  11 |
|  13 |
|  7  |
|  9  |
+-----+

As you can see, since the data is treated as string (according to the column datatype), then you could imagine this in alphabetical form as the following:

+-----+--------------+
| alc | alphabetical |
+-----+--------------+
|  11 |      AA      |
|  13 |      AC      |
|  7  |       G      |
|  9  |       I      |
+-----+--------------+

So, the condition of BETWEEN '7' AND '13' becomes BETWEEN 'G' AND 'AC'; which doesn't really make sense. And if you change to BETWEEN '11' AND '9' you'll get the correct result but that made the query even more confusing and not making sense at all.

Now, I've discovered that there are at least 3 workaround/solution for this:

  1. One of the oldest way I can think of is by adding +0 to the column in the query. I didn't find any official docs about this but I assume that doing this will change the data value to numeric in the query:
         SELECT * FROM table1 
            WHERE alc+0 BETWEEN '7' AND '13';
  1. This is probably the same as above is just that I'm not sure if this is version specific or not. It turns out that in my testing, if you didn't wrap the searched value in quotes, you'll get the result as if the data is numeric:
         SELECT * FROM table1 
            WHERE alc BETWEEN 7 AND 13;
  1. This require a change of column datatype but afterwards any of the query with or without quotes on the searched value should work:
         ALTER TABLE table1 CHANGE alc alc INT;

I hope that this is true and the issue is really about column datatype. As far as I know, this is the closest thing to what your situation is that I had experience with.

Here's a fiddle for reference

FanoFN
  • 6,815
  • 2
  • 13
  • 33
  • I think we didnt understand each other, maybe I have writteen that down unclearly. I havre slider filter for atribut "alc". So I have for example five products with "alc" 7,8,11,13,15. If I have filter with "alc_min" = 7 and "alc_max" = 9, it gives me back 2 results (7 and 8) and its fine. If "alc_min" = 10 and "alc_max" = 13, it gives me also 2 results (11 and 13). But if "alc_min" = 7 and "alc_max" = 13, I expect 4 results (7,8,11,13) but I get nothing. I just found that if "alc_min" in the filter is under 10 and "alc_max" is upper ten, it is broken and I dont have any idea why. – Jaroslav Hor Sep 18 '21 at 16:31
  • Sorry, I didn't notice there was a reply. Can I get the table structure and the raw MySQL query that you were doing? You can run `SHOW CREATE TABLE table_name` and [post the result into your question](https://stackoverflow.com/posts/69232024/edit). I have a hunch that this might be caused by the column datatype but I need to know see the table structure and the raw query to confirm it. – FanoFN Oct 20 '21 at 02:46
  • Thx for your edit. Maybe this is it, but now I need to find functional solution. I dont build query on direct and also I cant change datatype in database. Data are stored in meta key/value format for all parameters, so it is "longtext". I can transform data on input to float value, but it doesnt help. If I change min and max in the query, it gives me also bad results (only items with that min and max). I tried now some more things, but I dont find a solution. But I think this is the way! Thx for it. – Jaroslav Hor Oct 22 '21 at 11:49
  • 1
    Well, finally thx to your advice I found the problem and solution. when I fcus on solving dataset, I found that there is two types in WP Query. I used "numeric", but correct is "decimal". Now it takes floats as floats and can cmpare them and it seems that it is working now. Thx a lot! – Jaroslav Hor Oct 22 '21 at 18:37
  • I'm glad it all work out for you in the end. If my suggestion helped, you can accept as answer. If my suggestion only help a bit and you've constructed a more thorough solution, you can post you own answer and accept it. Here's a guide on [how to accept an answer](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) – FanoFN Oct 23 '21 at 00:37
  • 1
    You have found the way, the main point. I just found solution thx to your advice. So your answer is correct, but I cant use it as it stand in WordPress. Thx again for your patiance and help :) – Jaroslav Hor Oct 24 '21 at 07:50