【问题标题】:Order a SQL Query by number of results按结果数对 SQL 查询进行排序
【发布时间】:2011-09-28 16:53:03
【问题描述】:

我想做以下事情:

$searchParams 是一个数组,其中包含一些字符串(动态生成)。

现在声明会是这样的:

SELECT manufacturer FROM shop_articles WHERE manufacturer LIKE '".$searchParams."%'

但我想要的是匹配最多的结果。我可以在一个语句中编码吗? 所以会是这样的

ORDER BY MATCHES DESC

我该怎么做?

【问题讨论】:

  • 您想要计算结果的数量吗?就像如果你想要一些像输入字符串一样具有制造商的行?
  • 当您说匹配时,您的意思是如果 searchParams 包含 4 个关键字并且其中 3 个存在于字符串中,那么 MATCHES = 3 ?
  • 不是我的意思是,我想要行数最多的制造商。假设我输入了两个制造商,所以 $searchParams 将包含这两个字符串,我想知道这两个字符串中哪一个在数据库中的产品最多,并返回该制造商的名称

标签: php mysql sql


【解决方案1】:
SELECT COUNT(*) AS matches, manufacturer FROM shop_articles WHERE manufacturer LIKE '".$searchParams."%' GROUP BY(manufaturer) ORDER BY matches ASC

【讨论】:

    【解决方案2】:

    SELECT 制造商,COUNT(manufacturer) FROM shop_articles WHERE manufacturer LIKE '".$searchParams."' GROUP BY Manufacturer ORDER BY COUNT(manufacturer) DESC

    【讨论】:

      【解决方案3】:

      实际上,您必须衡量制造商和 $searchParam 之间的匹配度(相似度)。不幸的是 LIKE 不提供这样的功能。 您可以使用 Lavenshtein 距离。看到这个帖子 - Implementation of Levenshtein distance for mysql/fuzzy search?

      【讨论】:

        【解决方案4】:

        对于 searchParam 数组中的每个参数,您必须创建一个 like 子句

            SELECT Manufacturer, COUNT(*) AS Matches FROM
            FROM shop_articles WHERE (
        manufacturer LIKE '".$searchParams[0]."%' OR
        manufacturer LIKE '".$searchParams[1]."%' OR 
        ...
        manufacturer LIKE '".$searchParams[n]."%' OR )
            GROUP BY Manufacturer
            ORDER BY Matches
        

        【讨论】:

        • 只返回按其在数组中的位置排序的制造商名称。但是我想知道,这些厂家哪家的db产品最多。
        • 根据您的 cmets 更新
        【解决方案5】:

        不,您不能将数组提交给 LIKE 运算符。比这更乏味。 :-)

        当您的数据尚未正确规范化时,因此您在 PRODUCTS 表中有制造商名称的变体(例如“HP”、“Hewlett Packard”)而不是整数制造商 ID,您必须完成繁重的工作将这些变体简化为一个实体。

        执行该(相当不可避免的)工作的典型方法是创建如下所示的制造商表:

          Table: MANUFACTURER
        
                           manufacturerid  INTEGER primary key
                           manufacturername  varchar
                           primarymanufacturerid  INTEGER  FOREIGN KEY REFERENCES MANUFACTURER(manufacturerid)
        

        最后一列允许您将变体名称(例如“HP”)与存储主要制造商记录的行(例如“Hewlett Packard”)相关联。

                           124,   Hewlett Packard,    124
                           367,   HP,                 124
        

        primarymanufacturerid = Manufacturerid 的行是主要实体。

        然后您可以在临时清理阶段执行此操作,此时您尚未将制造商 ID 添加到 PRODUCTS 表但它仍然具有名称:

                         select * from products 
                         where manufacturer in
                         (
                           select manufacturername from manufacturer
                           where primarymanufacturerid = 
                            (
                             select primarymanufacturerid from manufacturer
                             where manufacturername = 'Hewlett Packard'
                             )
                         )
        

        附:使用支持函数和存储过程的数据库引擎,您可以编写自己的函数来接受分隔的名称变体字符串,构建动态 SQL 语句,可能使用临时表来存储变体名称,每行一个名称,并且返回匹配的计数。这将是一种资源密集型方法,建议仅用于协助清理阶段——而不是我将其投入生产以供最终用户作为日常面包消费。

        附言当然,一旦您正确创建了 MANUFACTURER 表,并完成了 primarymanufacturerid 引用,您可以将 [manufacturerid] 列添加到 PRODUCTS 表并相应地更新它,然后省去所有这些迂回的东西。

        【讨论】:

        • 数据是正则化的,但问题是,这个数组包含制造商和产品。我想知道,哪些价值观是制造商,哪些价值观是产品。如果可能的话,我想在一个 SQL 语句中得到它
        【解决方案6】:

        $sql = '从 shop_articles WHERE 1=1 中选择制造商'; 对于($i=0;$i

        通过这个你可以动态地运行 $searchParams 数组的查询

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-08-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-30
          • 2018-12-15
          • 2012-07-14
          相关资源
          最近更新 更多