简体   繁体   中英

Order a SQL Query by number of results

I want to do the following:

$searchParams is an array, which contains some strings (dynamicly generated).

Now the Statement would be something like this:

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

But what I want is the result with the most matches. Can I code that in one statement? So it would be something like

ORDER BY MATCHES DESC

How do I do that?

SELECT COUNT(*) AS matches, manufacturer FROM shop_articles WHERE manufacturer LIKE '".$searchParams."%' GROUP BY(manufaturer) ORDER BY matches ASC

Actually you have to measure matching (likeness) between manufacturer and $searchParam. Unfortunatelly LIKE does not provide such functionality. You may use Lavenshtein distances. See this post - Implementation of Levenshtein distance for mysql/fuzzy search?

For each param in your searchParam array you have to make a like clause

    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

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

No, you cannot submit an array to the LIKE operator. It is more tedious than that. :-)

When your data are not yet properly regularized, so that you have variants of the manufacturer name in the PRODUCTS table (eg "HP", "Hewlett Packard") rather than an integer ManufacturerID, you have to go through the grunt work of reducing those variants to a single entity.

A typical approach for doing that (quite unavoidable) work is to create a Manufacturers table like this:

  Table: MANUFACTURER

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

The last column allows you to associate a variant name (eg "HP") with the row where the main manufacturer record is stored (eg "Hewlett Packard").

                   124,   Hewlett Packard,    124
                   367,   HP,                 124

The row where primarymanufacturerid = manufacturerid is the the main entity.

Then you could do this during an interim cleanup phase when you have not yet added a manufacturerid to the PRODUCTS table but it still has the name:

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

PS With a database engine that had support for functions and stored procedures, you could write your own function that accepted a delimited string of name variations, built a dynamic SQL statement, possibly using a temporary table to store the variant names one name per row, and returned a count of the matches. This would be a resource-intensive approach recommended only to assist in the clean-up phase -- not something I'd put into production for end-users to consume as their daily bread.

PPS And, of course, once you have your MANUFACTURER table properly created, with the primarymanufacturerid references completed, you could add a [manufacturerid] column to your PRODUCTS table and update it accordingly, and then dispense with all of this roundabout stuff.

$sql = 'SELECT manufacturer FROM shop_articles WHERE 1=1'; for($i=0;$i

by this you can run query for $searchParams array dynamically

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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