简体   繁体   English

Sql选择列中的数组

[英]Sql select where array in column

In my query I use join table category_attributes .在我的查询中,我使用连接表category_attributes Let's assume we have such rows:假设我们有这样的行:

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

I want to have the query which suites the two following needs.我想要满足以下两个需求的查询。 I have a variable (php) of allowed attribute_id's .我有一个允许attribute_id's变量(php)。 If the array is subset of attribute_id then category_id should be selected, if not - no results.如果数组是attribute_id的子集,那么应该选择category_id ,如果不是 - 没有结果。

First case:第一种情况:

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

should give no results.应该没有结果。

Second case第二种情况

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

should give all three rows (see dummy rows at the beginning).应该给出所有三行(参见开头的虚拟行)。

So I would like to have reverse side of what standard SQL in does.所以我想了解标准 SQL in作用的反面。

Solution解决方案

Step 1: Group the data by the field you want to check.第 1 步:按要检查的字段对数据进行分组。

Step 2: Left join the list of required values with the records obtained in the previous step.步骤 2:将所需值列表与上一步中获得的记录左连接。

Step 3: Now we have a list with required values and corresponding values from the table.第 3 步:现在我们有一个包含所需值和表中相应值的列表。 The second column will be equal to required value if it exist in the table and NULL otherwise.如果第二列存在于表中,则第二列将等于所需值,否则为NULL

步骤 3 输出

Count null values in the right column.计算右列中​​的空值。 If it is equal to 0, then it means table contains all the required values.如果等于 0,则表示 table 包含所有必需的值。 In that case return all records from the table.在这种情况下,返回表中的所有记录。 Otherwise there must be at least one required value is missing in the table.否则,表中必须至少缺少一个必需的值。 So, return no records.因此,不返回任何记录。


Sample样本

Table "Data":表“数据”:

表数据

Required values:所需值:
10, 20, 50

Query:询问:

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;

You can use group by and having :您可以使用group byhaving

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

This assumes that the table has no duplicates (which is typical for attribute mapping tables).这假定该表没有重复项(这是属性映射表的典型情况)。 If that is a possibility, use:如果有可能,请使用:

having count(distinct ca.attribute_id) = 4

You can aggregate attribute_id into array and compare two array from php.您可以将attribute_id聚合到数组中并比较来自 php.ini 的两个数组。

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

But you need to find another way to compare arrays or make sure that array is always sorted.但是您需要找到另一种方法来比较数组或确保数组始终是排序的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM