多个find_in_set()mysql给出了错误的结果

时间:2016-11-28 06:54:30

标签: mysql

这是我的问题:

SELECT p . * , f . * ,
CASE WHEN CAST( p.product_special_price AS DECIMAL ) > CAST( p.product_price AS DECIMAL )
THEN CAST( p.product_price AS DECIMAL )
ELSE
CASE WHEN CAST( p.product_special_price AS DECIMAL ) =0
THEN CAST( p.product_price AS DECIMAL )
ELSE CAST( p.product_special_price AS DECIMAL )
END
END AS MinPrice1
FROM crm_products p
JOIN `crm_seller_attributes` sa ON sa.seller_id = p.seller_id
LEFT JOIN `crm_product_filter` f ON p.product_id = f.product_id
AND f.seller_id = p.seller_id
WHERE p.seller_id = '63'
AND (
FIND_IN_SET( '338', f.seller_attribute_id )
OR FIND_IN_SET( '340', f.seller_attribute_id )
)
AND (
FIND_IN_SET( '737', f.options )
OR FIND_IN_SET( '736', f.options )
OR FIND_IN_SET( '749', f.options )
)
AND FIND_IN_SET( '515', p.category_ids )
AND p.product_status = 'Active'
GROUP BY p.product_id
ORDER BY p.product_id DESC
LIMIT 0 , 12

小提琴:

http://sqlfiddle.com/#!9/2e9ee9/1

expecting : `productname` 'sjadduu' should not be there

更新了小提琴:

http://sqlfiddle.com/#!9/2e9ee9/18

当前结果

FIND_IN_SET(' 338',f.seller_attribute_id) 或者FIND_IN_SET(' 340',f.seller_attribute_id) )

从此只考虑第一个条件FIND_IN_SET( '338', f.seller_attribute_id )并给出结果,而不是试图检查OR FIND_IN_SET( '340', f.seller_attribute_id )的休息条件

预期结果:

应检查两者:

FIND_IN_SET( '338', f.seller_attribute_id )
OR FIND_IN_SET( '340', f.seller_attribute_id )
)

我们尝试了

FIND_IN_SET( '338', f.seller_attribute_id )
**AND** FIND_IN_SET( '340', f.seller_attribute_id )
)

但没有找到结果,我们期待总共2条记录

2 个答案:

答案 0 :(得分:2)

您似乎在整数字段上使用FIND_IN_SET(不包含列表)。如果要检查该整数字段的值是否为值列表之一,则更快使用IN

SELECT p . * , 
        f . * ,
CASE 
WHEN CAST( p.product_special_price AS DECIMAL ) > CAST( p.product_price AS DECIMAL )
    THEN CAST( p.product_price AS DECIMAL )
    ELSE
        CASE WHEN CAST( p.product_special_price AS DECIMAL ) =0
            THEN CAST( p.product_price AS DECIMAL )
            ELSE CAST( p.product_special_price AS DECIMAL )
        END
    END AS MinPrice1
FROM crm_products p
JOIN `crm_seller_attributes` sa ON sa.seller_id = p.seller_id
LEFT JOIN `crm_product_filter` f ON p.product_id = f.product_id AND f.seller_id = p.seller_id
WHERE p.seller_id = '63'
AND (f.seller_attribute_id IN (338, 340))
AND (FIND_IN_SET( '737', f.options )
OR   FIND_IN_SET( '736', f.options )
OR   FIND_IN_SET( '749', f.options ))
AND  FIND_IN_SET( '515', p.category_ids )
AND  p.product_status = 'Active'
GROUP BY p.product_id
ORDER BY p.product_id DESC
LIMIT 0 , 12

修改

当您拥有所有选定的过滤器时,您似乎只需要一个产品(这不是您的样本数据中的情况)。

几个解决方案。最简单的方法是只计算不同的属性并检查它与搜索的属性相同: -

SELECT p . * , 
        f . * ,
CASE 
WHEN CAST( p.product_special_price AS DECIMAL ) > CAST( p.product_price AS DECIMAL )
    THEN CAST( p.product_price AS DECIMAL )
    ELSE
        CASE WHEN CAST( p.product_special_price AS DECIMAL ) =0
            THEN CAST( p.product_price AS DECIMAL )
            ELSE CAST( p.product_special_price AS DECIMAL )
        END
    END AS MinPrice1
FROM crm_products p
INNER JOIN `crm_seller_attributes` sa ON sa.seller_id = p.seller_id
INNER JOIN `crm_product_filter` f ON p.product_id = f.product_id AND f.seller_id = p.seller_id
WHERE p.seller_id = '63'
AND (f.seller_attribute_id IN (338, 340))
AND (FIND_IN_SET( '737', f.options )
OR   FIND_IN_SET( '736', f.options )
OR   FIND_IN_SET( '749', f.options ))
AND  FIND_IN_SET( '515', p.category_ids )
AND  p.product_status = 'Active'
GROUP BY p.product_id
HAVING COUNT(DISTINCT f.seller_attribute_id) = 2
ORDER BY p.product_id DESC
LIMIT 0 , 12

另一种方法是为每个过滤器加入一次表。在这种情况下,我已将过滤器上的检查移动到ON子句,以便更容易阅读。

SELECT p.* , 
        f1.* ,
CASE 
WHEN CAST( p.product_special_price AS DECIMAL ) > CAST( p.product_price AS DECIMAL )
    THEN CAST( p.product_price AS DECIMAL )
    ELSE
        CASE WHEN CAST( p.product_special_price AS DECIMAL ) =0
            THEN CAST( p.product_price AS DECIMAL )
            ELSE CAST( p.product_special_price AS DECIMAL )
        END
    END AS MinPrice1
FROM crm_products p
INNER JOIN `crm_seller_attributes` sa ON sa.seller_id = p.seller_id
INNER JOIN `crm_product_filter` f1 ON p.product_id = f1.product_id AND f1.seller_id = p.seller_id AND f1.seller_attribute_id  = 338 AND (FIND_IN_SET( '737', f1.options ) OR FIND_IN_SET( '736', f1.options ) OR FIND_IN_SET( '749', f1.options ))
INNER JOIN `crm_product_filter` f2 ON p.product_id = f2.product_id AND f2.seller_id = p.seller_id AND f2.seller_attribute_id  = 340 AND (FIND_IN_SET( '737', f2.options ) OR FIND_IN_SET( '736', f2.options ) OR FIND_IN_SET( '749', f2.options ))
WHERE p.seller_id = '63'
AND  FIND_IN_SET( '515', p.category_ids )
AND  p.product_status = 'Active'
GROUP BY p.product_id
ORDER BY p.product_id DESC
LIMIT 0 , 12

在任何一种情况下,您都有一个问题,即您要从过滤器表中返回所有列,但使用GROUP BY p.product_id。这将导致返回一行匹配过滤器,但未定义哪一行。

答案 1 :(得分:1)

因此,您必须修改 FIND_IN_SET 。 fieldlist是第二个参数

示例

SELECT p . * , f . * ,
CASE WHEN CAST( p.product_special_price AS DECIMAL ) > CAST( p.product_price AS DECIMAL )
THEN CAST( p.product_price AS DECIMAL )
ELSE
CASE WHEN CAST( p.product_special_price AS DECIMAL ) =0
THEN CAST( p.product_price AS DECIMAL )
ELSE CAST( p.product_special_price AS DECIMAL )
END
END AS MinPrice1
FROM crm_products p
JOIN `crm_seller_attributes` sa ON sa.seller_id = p.seller_id
LEFT JOIN `crm_product_filter` f ON p.product_id = f.product_id AND f.seller_id = p.seller_id

WHERE p.seller_id = '63'
AND FIND_IN_SET( CAST(f.seller_attribute_id as CHAR),'338,340' )
AND (
    FIND_IN_SET( '736', CAST(f.options as CHAR)) OR
    FIND_IN_SET( '737', CAST(f.options as CHAR)) OR
    FIND_IN_SET( '749', CAST(f.options as CHAR))
)
AND FIND_IN_SET( '515', CAST(p.category_ids as CHAR))
AND p.product_status = 'Active'
GROUP BY p.product_id
ORDER BY p.product_id DESC
LIMIT 0 , 12;

<强>结果

+------------+-----------+---------------+--------------------------------+---------------+-----------------------+--------------------------------+-------------------+-------------+-------------------------------------+-------------+-----------------+-----------------+----------------+----------------------------+----------------------------+---------------------+----------------+---------------+----------------+---------------+--------------------+-----------+-----------+------------+---------------------+---------+-----------+
| product_id | seller_id | product_type  | product_name                   | product_price | product_special_price | product_sku                    | category_ids      | product_upc | product_image                       | product_qty | product_min_qty | product_max_qty | product_weight | short_description          | long_description           | created_at          | product_status | product_width | product_height | product_depth | product_sort_order | filter_id | seller_id | product_id | seller_attribute_id | options | MinPrice1 |
+------------+-----------+---------------+--------------------------------+---------------+-----------------------+--------------------------------+-------------------+-------------+-------------------------------------+-------------+-----------------+-----------------+----------------+----------------------------+----------------------------+---------------------+----------------+---------------+----------------+---------------+--------------------+-----------+-----------+------------+---------------------+---------+-----------+
|       1579 |        63 | simple-custom | sjadduu                        |           500 |                    15 | erettrtr                       | 86,515,87,515,620 |             | NULL                                | 100         | 1               |              10 | NULL           | NULL                       | NULL                       | 2016-11-25 11:36:53 | Active         | NULL          | NULL           | NULL          |               NULL |       407 |        63 |       1579 |                 338 | 736     |        15 |
|       1415 |        63 | simple-custom | Double Cheesy Margherita Pizza |           170 |                     0 | Double Cheesy Margherita Pizza | 515,87,515        |             | 1479557588_235.png                  | 100         | 1               |             100 |                |                            |                            | 2016-11-19 12:25:51 | Active         |               |                |               |                  0 |       289 |        63 |       1415 |                 338 | 737,736 |       170 |
|       1406 |        63 | simple-custom | Cheese Burst Pizza             |           250 |                     0 | 123456                         | 515,87,515        |             | 1479116616_pizza_trad_pepperoni.png | 97          | 1               |             100 |                | <p>chesse burst pizza</p>
 | <p>chesse burst pizza</p>
 | 2016-11-21 06:09:41 | Active         |               |                |               |                  0 |       256 |        63 |       1406 |                 338 | 737,736 |       250 |
+------------+-----------+---------------+--------------------------------+---------------+-----------------------+--------------------------------+-------------------+-------------+-------------------------------------+-------------+-----------------+-----------------+----------------+----------------------------+----------------------------+---------------------+----------------+---------------+----------------+---------------+--------------------+-----------+-----------+------------+---------------------+---------+-----------+
3 rows in set (0,01 sec)