Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从MySQL表中选择按一列分组的行,并在另一列中选择所需的值_Sql_Mysql_Database - Fatal编程技术网

如何从MySQL表中选择按一列分组的行,并在另一列中选择所需的值

如何从MySQL表中选择按一列分组的行,并在另一列中选择所需的值,sql,mysql,database,Sql,Mysql,Database,我需要筛选某些属性存储在符合所有必需属性的联接表中的产品,即用户需要能够通过添加需求逐步缩小搜索范围 考虑到以下简化的产品属性表,问题实际上只涉及属性表,而不是连接: id product_id property value --------------------------------- 1 1 color red 2 1 size small 3 2 color red 4 2

我需要筛选某些属性存储在符合所有必需属性的联接表中的产品,即用户需要能够通过添加需求逐步缩小搜索范围

考虑到以下简化的产品属性表,问题实际上只涉及属性表,而不是连接:

id product_id property value --------------------------------- 1 1 color red 2 1 size small 3 2 color red 4 2 size large 这是可行的,但我担心性能,似乎有更好的方法

最终,这将需要与products表连接,或至少用于过滤products表:

id name ------------- 1 Product 1 2 Product 2 我忘了提到,我有两个属性表连接到我需要筛选的产品,一个具有产品的常规属性,另一个具有类似变体的可用可配置选项。 该场景允许用户过滤以下产品: 显示性别为“男性”、品牌为“nike”和尺码为“小型”的产品,其中性别和品牌为“属性”,尺码在添加到购物车时可在选项中配置

使用带有计数的组的解决方案仍然适用于两个联接的表,但会变得混乱,所需的组计数是第一个表上所需选项的数量乘以第二个表上的数量


我可以只从属性和另一个表中获取id,然后只做一个select where id INID,为两个属性表匹配一组id,但我不喜欢使用非常长的id列表来执行此操作。

不确定这是否更快,但是从您的筛选条件生成的子查询中进行连接可以工作:

Select p.name, p.id from product p, 
(select product_id from properties where value='red') colors,
(select product_id from properties where value='small') sizes
where p.id=colors.product_id and p.id=sizes.product_id

您可以将表连接到自身:

SELECT
prop1.product_id
FROM
properties prop1
JOIN properties prop2
    ON prop1.product_id = prop2.product_id
WHERE
prop1.property = 'color' and prop1.value = 'red'
and prop2.property = 'size' and prop2.value = 'small'

属性值数据模型的另一个陷阱

假设您想要颜色匹配红色、大小匹配小尺寸的产品,您在问题中不会说属性实际上很重要,只是值,问题的很大一部分是,您如何表示所需匹配的列表?它们是否会作为分隔字符串传递、存储在临时表中、动态构建的SQL或其他内容

如果可以将它们临时或以其他方式放入表中,那么以下查询应该可以工作。由于子查询的存在,性能将非常依赖于您正在处理的数据量及其索引方式。此外,如果同一产品的表中有重复的属性,那么它可能会出错,因此您可能需要对此进行说明

SELECT
    P.*
FROM
    Products P
WHERE
    NOT EXISTS
    (
        SELECT
            *
        FROM
            Product_Search_Template PST
        LEFT OUTER JOIN Properties P2 ON
            P2.property = PST.property AND
            P2.value = PST.value AND
            P2.product_id = P.product_id
        WHERE
            P2.id IS NULL
    )


在您的示例中,当组计数大于2时会发生什么情况?他们将被排除在外。我想你应该把它当作组计数>0谢谢,这确实有效。我将比较性能。为了使事情变得更复杂,我有另一个属性类型表要连接并以相同的方式进行过滤,但使用这种方法,应该很容易涉及到另一个表。谢谢,这是可行的,但我担心如果我必须将表连接到自身超过2次,它将如何执行。它将与任何其他解决方案一样执行,特别是子查询方法。将表连接到自身本身并不是性能杀手。请从属性p1、属性p2、产品pn中选择不同的p1.product_id、pn.product,其中p1.product_id=p2.product_id和p1.product='size'和p1.value='small'和p2.product='color'和p2.value='red'和pn.id=p1.product_id我测试了此查询。这将足够快。你是对的,属性名称并不重要,只是值。在实际表中,名称和值都是外键。我将动态构建SQL,所需的值来自数组。我最终需要在同一个查询中过滤另一个属性类型表。那么,你的意思是,如果它们的大小很小,或者分布范围很小,那么搜索“小”时应该对它们进行相同的处理?那不是我编码的目的。当我使用真正的键盘时,我会把它清理干净。
SELECT
prop1.product_id
FROM
properties prop1
JOIN properties prop2
    ON prop1.product_id = prop2.product_id
WHERE
prop1.property = 'color' and prop1.value = 'red'
and prop2.property = 'size' and prop2.value = 'small'
SELECT
    P.*
FROM
    Products P
WHERE
    NOT EXISTS
    (
        SELECT
            *
        FROM
            Product_Search_Template PST
        LEFT OUTER JOIN Properties P2 ON
            P2.property = PST.property AND
            P2.value = PST.value AND
            P2.product_id = P.product_id
        WHERE
            P2.id IS NULL
    )
SELECT
    P.*
FROM
(
    SELECT
        PROP1.product_id,
        COUNT(*) AS match_count
    FROM
        Properties PROP1
    INNER JOIN Product_Search_Template PST ON
        PST.property = PROP1.property AND
        PST.value = PROP1.value
    GROUP BY
        PROP1.product_id
) SQ
INNER JOIN Products P ON
    P.product_id = SQ.product_id
WHERE
    SQ.match_count = (SELECT COUNT(*) FROM Product_Search_Template)