代码之家  ›  专栏  ›  技术社区  ›  FreeLightman

SQL选择列中的位置数组

  •  -2
  • FreeLightman  · 技术社区  · 5 年前

    在查询中,我使用联接表 category_attributes . 假设我们有这样的行:

    category_id|attribute_id
    1|1
    1|2
    1|3
    

    我想得到满足以下两个需求的查询。我有一个允许的变量(php) attribute_id's . 如果数组是 attribute_id 然后 category_id 应该被选中,如果没有-没有结果。

    第一种情况:

    select * from category_attributes where (1,2,3,4) in category_attributes.attribute_id
    

    应该没有结果。

    第二例

    select * from category_attributes where (1,2,3) in category_attributes.attribute_id
    

    应给出所有三行(请参阅开头的虚行)。

    所以我想有什么标准sql的反面 in 做。

    1 回复  |  直到 5 年前
        1
  •  0
  •   Bertram Gilfoyle    5 年前

    解决方案

    步骤1: 按要检查的字段对数据进行分组。

    步骤2: 将所需值的列表与上一步中获得的记录左键联接。

    步骤3: 现在我们有一个列表,其中包含必需的值和表中相应的值。如果第二列存在于表中,并且 NULL 否则。

    Step 3 output

    在右列中计算空值。如果等于0,则表示表包含所有必需的值。在这种情况下,返回表中的所有记录。否则,表中必须至少缺少一个必需的值。所以,不要返回任何记录。


    样品

    表“数据”:

    Table data

    必需值:
    10, 20, 50

    查询:

    SELECT * 
    FROM   Data 
    WHERE  (SELECT Count(*) 
            FROM   (SELECT D.value 
                    FROM   (SELECT 10 AS value 
                            UNION 
                            SELECT 20 AS value 
                            UNION 
                            SELECT 50 AS value) T 
                           LEFT JOIN (SELECT value 
                                      FROM   Data 
                                      GROUP  BY value) D 
                                  ON ( T.value = D.value )) J 
            WHERE  value IS NULL) = 0;
    
        2
  •  0
  •   Gordon Linoff    5 年前

    你可以使用 group by having :

    select ca.category_id
    from category_attributes ca
    where ca.attribute_id in (1, 2, 3, 4) 
    group by ca.category_id
    having count(*) = 4;  -- "4" is the size of the list
    

    这假设表没有重复项(这是属性映射表的典型情况)。如果有可能,请使用:

    having count(distinct ca.attribute_id) = 4
    
        3
  •  -1
  •   Elbek    5 年前

    你可以聚合 attribute_id 在数组中比较两个来自php的数组。

    SELECT category_id FROM 
    (select category_id, group_concat(attribute_id) as attributes from category_attributes
    order by attribute_id) t WHERE t.attributes = (1, 2, 3);
    

    但是您需要找到另一种方法来比较数组,或者确保数组始终是排序的。