MySQL查询-复杂计数条件

MySQL查询-复杂计数条件,mysql,optimization,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

我有一个带有以下结构的表“位置”:

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 | 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
我有另一个表“property”,其结构如下:

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(外键)。位置类型为

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查询来选择位置为1、位置为2、舒适度为1、属性为3、属性为1的属性id,即属性具有海滩、山脉、汽车、别墅和房屋:

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 
假设我将(位置为1、位置为2、设施为1、属性为3、属性为1的属性为id)的计数设为1500。我需要获得具有相同条件和其他属性类型、位置类型、设施类型的计数

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

  • (位置类型为1、位置类型为2、设施类型为1、属性类型为3、属性类型为1的属性id)和位置类型为3的计数

  • (位置类型为1、位置类型为2、设施类型为1、属性类型为3、属性类型为1的属性id)和位置类型为4的计数

  • (位置类型为1,位置类型为2,设施类型为1,属性类型为3,属性类型为1的属性id)和设施类型为2的计数

  • (位置类型为1,位置类型为2,设施类型为1,属性类型为3,属性类型为1的属性id)和设施类型为3的计数

  • 是否有任何有效的方法来获取不同位置类型、舒适度类型等的计数


    请参阅我前面的问题-

    由于以下原因,您的查询失败:

    property_type = 3 AND property_type = 1
    
    单个字段不能同时具有两个值。应该是

    ... AND ... (property_type = 3 OR property_type = 1) AND ...
    
    或者更具可读性:

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

    对于
    位置类型
    便利设施类型
    字段也是如此。

    由于以下原因,您的查询失败:

    property_type = 3 AND property_type = 1
    
    单个字段不能同时具有两个值。应该是

    ... AND ... (property_type = 3 OR property_type = 1) AND ...
    
    或者更具可读性:

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

    location\u type
    amerity\u type
    字段也是如此。

    我理解这个问题有点困难,但我想您是在询问有关与基本过滤器匹配的属性的更多信息

    您可以尝试以下方法:

    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
    
    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 
    
    您可以从此处展开联接列表和条件


    编辑:根据您的评论,我认为您需要添加逻辑分组…

    我理解这个问题有点困难,但我认为您是在询问有关与基本筛选器匹配的属性的附加信息

    您可以尝试以下方法:

    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
    
    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 
    
    您可以从此处展开联接列表和条件


    编辑:根据您的评论,我认为您需要添加逻辑分组…

    您可以使用基本查询获取所有
    属性.id
    (并计算它们)和
    选择
    列表中的子查询来计算附加条件,如下所示:

    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
    
    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 
    

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

    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
    
    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 
    

    抱歉,我之前没有澄清,但计数条件不是查询,它们只是定义我想要的属性\u id的计数,该属性的位置\u type=1、位置\u type=2、舒适性\u type=1、属性\u type=3、属性\u type=1(所有强制条件)-这是一个搜索应用程序。对不起,我之前没有澄清,但是计数条件不是查询,它们只是定义我想要的属性id的计数,它的位置类型=1,位置类型=2,舒适类型=1,属性类型=3,属性类型=1(所有强制条件)-这是一个搜索应用程序。谢谢Doug,但我不想选择属性,但我想用我的基本过滤器和每个位置类型、设施类型选择计数。听起来你需要使用分组方式。。。使用ROLLUP。重新考虑上述内容,您可能希望从SELECT列表和GROUP BY子句中删除p.id,以统计基本筛选器中的所有属性(而不是每个属性的位置/便利设施计数,这似乎没有帮助)。谢谢Doug,但我不想选择属性,但我想用我的基本过滤器和每个位置类型、设施类型选择计数。听起来你需要使用分组方式。。。使用ROLLUP.REFINATING,您可能希望从SELECT列表和GROUP BY子句中删除p.id,以统计基本筛选器中的所有属性(而不是每个属性的位置/便利设施计数,这似乎没有帮助).因此,您需要一些基本情况下的计数,以及在每个不同情况下您将获得的计数,在这些情况下,您保持所有内容不变,但改变一个参数?所以这会产生很多不同的计数?你真的需要所有这些不同的组合吗?或者它只是一些子集?是的,我需要基本计数和基于基本条件的计数,并添加另一个参数,以便我可以向用户显示如果您也选择此位置类型,有多少属性可用。我们真的需要展示所有不同的组合。与之非常相似的是,在这里你可以看到左边过滤器上的计数。那么你想要一些基本情况下的计数,以及在每个不同情况下得到的计数,在这些情况下,你保持所有内容不变,但改变一个参数?所以这会产生很多不同的计数?你真的需要所有这些不同的组合吗?或者它只是一些子集?是的,我需要基本计数和基于基本条件的计数,并添加另一个参数,以便我可以向用户显示如果您也选择此位置类型,有多少属性可用。我们真的需要展示所有不同的组合