MySQL查询 - 复杂计数条件

时间:2011-08-18 18:04:01

标签: mysql optimization

我有一个表格“位置”,结构如下:

id  | property_id | location_type
1   | 1           | 1
2   | 1           | 2
3   | 2           | 1
4   | 3           | 2
5   | 4           | 1
6   | 4           | 2

我还有另一张桌子“设施”,结构如下:

id  | property_id | amenity_type
1   | 1           | 1
2   | 1           | 3
3   | 2           | 2
4   | 3           | 4
5   | 4           | 1
6   | 4           | 3

我有另一个表格“属性”,其结构为:

id  | property_id | property_type
1   | 1           | 2
2   | 1           | 3
3   | 2           | 2
4   | 3           | 4
5   | 4           | 2
6   | 4           | 3

id - 是相应表的主键。 property_id是我的数据库(外键)的属性ID。 location_type是

beach (value - 1), mountain (value - 2).

amenity_type is car (value - 1), bike (value - 2), football (value - 3).

property_type is villa (value - 2), house (value - 3)

我正在使用以下SQL查询来选择property_id,其中location_type = 1 AND location_type = 2 AND amenity_type = 1 AND property_type = 3 AND property_type = 1即属性有海滩和山脉以及汽车和别墅和房屋:< / p>

SELECT p.id  
FROM 
    property AS p           
  JOIN
    location AS l1
        ON  l1.property_id = p.id  
        AND l1.location_type = 1 
  JOIN
    location AS l2
        ON  l2.property_id = p.id  
        AND l2.location_type = 2 
  JOIN                      
    amentities AS a1
        ON  a1.property_id = p.id
        AND a1.amenity_type = 2                 
  JOIN
    properties AS p1
        ON  p1.property_id = p.id  
        AND p1.property_type = 3 
  JOIN
    properties AS p2 
        ON  p2.property_id = p.id  
        AND p2.property_type = 1 

假设我得到(property_id,其中location_type = 1 AND property_type = 2 AND amenity_type = 1 AND property_type = 3 AND property_type = 1)为1500.我需要获得具有相同条件的计数和其他property_type,location_type, amenity_type。

但是我无法使用上述查询获得以下条件的计数:

  1. 计数(property_id,其中location_type = 1 AND location_type = 2 AND amenity_type = 1 AND property_type = 3 AND property_type = 1)AND location_type = 3

  2. 计数(property_id,其中location_type = 1 AND location_type = 2 AND amenity_type = 1 AND property_type = 3 AND property_type = 1)AND location_type = 4

  3. 计数(property_id,其中location_type = 1 AND location_type = 2 AND amenity_type = 1 AND property_type = 3 AND property_type = 1)AND amenity_type = 2

  4. 计数(property_id,其中location_type = 1 AND location_type = 2 AND amenity_type = 1 AND property_type = 3 AND property_type = 1)AND amenity_type = 3

  5. 是否有任何有效的方法来获取具有不同location_type,amenity_type等的计数。

    请参阅我之前的问题 - MySQL query - complex searching condition

3 个答案:

答案 0 :(得分:3)

您可以使用基本查询获取property.id列表中的所有SELECT(并计算它们)和子查询,以计算其他条件,如下所示:

SELECT COUNT(*) AS BaseCount
     , ( SELECT COUNT(*)
         FROM location AS l3
         WHERE l3.property_id = p.id  
           AND l3.location_type = 3
       ) AS CountLocation3
     , ( SELECT COUNT(*)
         FROM location AS l4
         WHERE l4.property_id = p.id  
           AND l4.location_type = 4
       ) AS CountLocation4
     , ( SELECT COUNT(*)
         FROM amenities AS a2
         WHERE a2.property_id = p.id  
           AND a2.amenity_type = 2
       ) AS CountAmenity4
     , ...
FROM 
    property AS p           
  JOIN
    location AS l1
        ON  l1.property_id = p.id  
        AND l1.location_type = 1 
  JOIN
    location AS l2
        ON  l2.property_id = p.id  
        AND l2.location_type = 2 
  JOIN                      
    amentities AS a1
        ON  a1.property_id = p.id
        AND a1.amenity_type = 1                 
  JOIN
    properties AS p3
        ON  p3.property_id = p.id  
        AND p3.property_type = 3 
  JOIN
    properties AS p1 
        ON  p1.property_id = p.id  
        AND p1.property_type = 1 

答案 1 :(得分:0)

您的查询因此失败:

property_type = 3 AND property_type = 1

单个字段不能同时具有两个值。它应该是

... AND ... (property_type = 3 OR property_type = 1) AND ...

或稍微更具可读性:

... AND ... property_type IN (1, 3) AND ...

同样适用于location_typeamenity_type字段。

答案 2 :(得分:0)

我在理解这个问题时遇到了一些困难,但我想您正在询问有关与您的基本过滤器匹配的属性的其他信息。

您可以尝试的一种方法是这样的:

SELECT p.id, l.location_type, a.amenity_type, count(*) property_count
FROM (
    SELECT p.id
    FROM property AS p           
        INNER JOIN location AS l1 ON l1.property_id = p.id AND l1.location_type = 1 
        INNER JOIN location AS l2 ON l2.property_id = p.id AND l2.location_type = 2 
        INNER JOIN amentities AS a1 ON  a1.property_id = p.id AND a1.amenity_type = 2                 
        INNER JOIN properties AS p1 ON  p1.property_id = p.id AND p1.property_type = 3 
        INNER JOIN properties AS p2 ON  p2.property_id = p.id AND p2.property_type = 1
) p
INNER JOIN location AS l ON l.property_id = p.id
INNER JOIN amentities AS a ON  a.property_id = p.id
GROUP BY p.id, l.location_type, a.amenity_type
WITH ROLLUP

您可以从那里扩展联接列表和条件。

编辑:根据您的评论,我认为您需要添加GROUP BY逻辑...