Using PHP and MySQL I need to find all "two word" combinations ordered by count from a table that has over a million rows.
The search needs to find how many instances of each two word combination, like "hardware store", "to the", "second chance", "for those", "senior citizens", etc.
Examples of text to search:
id | content
1 | The senior citizens went to the hardware store from the community center.
2 | The hardware store is offering a second chance drawing for those senior citizens who did not win.
3 | Many senior citizens go to the town's community center to play bingo.
Sample results:
senior citizens - 3
to the - 2
hardware store - 2
community center - 2
second chance - 1
The senior - 1
center to - 1
the town's - 1
etc ...and so on.
Results need to include all "two word" combinations. "The senior", went to", "the hardware", citizens went", etc., and the count of how many times found.
I'm guessing this might be a multiple query solution with sub queries, but my query building expertise is minimal. I have tried some basic queries, but am thinking the solution is going to be a bit more complex than my skill set.
Similar question with different data source.
Try a Union All join:
SELECT count(*) FROM your_table WHERE content LIKE '%senior citizens%'
UNION ALL
SELECT count(*) FROM your_table WHERE content LIKE '%to the%'
UNION ALL
SELECT count(*) FROM your_table WHERE content LIKE '%hardware store%'
Related
I think than search is one of most trivial problems in mysql, but i have an interesting request for online shop. By the way, I use Laravel v8 Eloquent for quering, if it helps with solution.
Lets assume that we have db table goods
id | name
1 | Fried chicken leg
2 | Chicken freezed
3 | Vegetable soup with chicks
4 | Enchickened grains
and when user type chicken I want to show first a lines that starts with search query (id 2 in example table), and it would be perfect if after those entries were those that have a search query as entire word (id 1) that starts with it, followed by any other line that contains search query. I ask about it primarily because of need of pagination since shop has a thousands of entries, so I do not want to make and merge results for few subsequent requests
I tried to make two requests and merge them, making a pagination out of these results, but I have quite complicated and rather expensive resulting request that touches a few relations for goods like promo, categories, blocks and few more, so it will be a twice or more as expensive and this is not something I want to see if there is a way to optimize a request.
EDIT Example:
If I enter chicken I want to see Chicken freezed first, then (ideally but not required) Fried chicken leg and after that anything that have chicken in it. if prioritize in regex: $chicken.* -> .*\bchicken.* -> %chicken% (last one for mysql)
Please help me how to create vertical menu or sub menu using these tables in PHP.
The two tables are cat(id,cat_name,main_cat_id) and main_cat(id,main_cat_name).
main_category table
id main_category_name
1 Hotels
2 Compressors
3 Apparel & Clothing
4 Automobile
5 Car Rentals
6 Mobiles & Accessories
7 Computers & Peripherals
8 Doctors
9 Education
category table
id category_name main_category_id
1 Pizza Center 1
2 2 Star Hotel 1
3 Hotel & Restaurant 1
4 5 Star Hotel 1
5 Air Compressor 2
6 Flare Nuts 2
7 Auto Accessories-Car Stereos 4
8 Automotive Parts, Components & Spares 4
9 Motorcycles, Scooters & Two Wheeler Parts 4
My policy of encouraging a prior attempt applies here. You've laid out the database, which is great, but you need to open a text editor and start on the PHP. You can do it!
Readers here could give you a working answer, but that suffers a number of drawbacks:
Firstly, they might misunderstand what you need, and so spend a long time on something that does not help you.
Secondly, there are several million people out there that would like people to work for them for free, and we'd be here until Doomsday if we did that.
Finally, if you get a working answer with no personal research, you might not learn anything.
Here's a suggested plan of action:
Install WAMP/MAMP/LAMP on your computer
Set up your database structure and test data in a MySQL instance on your development machine
Write some PHP code to connect to the database and run a test query on it, dumping the data in a web page
Once that works, modify the query to read the categories, using an ORDER clause to get them in the right order
Now you have enough information to create a menu. Look up the format of a <select> tag using <option> tags, each of which contains the name from your database. You'll need a value attribute for each one - this is usually the id from each row of the database
Wrap the above in a <form>
From here, you can expand your menu to contain a second level. The simplest way of doing that is to research the <optgroup> tag - much under-used, in my opinion. This allows you to set up a two-level menu that is intuitive for users and simple to read values from in code.
Give that a go?
I'm looking for a little bit of direction for how to analyze a problem. I work for a small manufacturing company. We paint about 150 items per day. Those items then go to Quality Control. About 70% pass QC. The remaining 30% have to be repaired in some way.
We have 5 different repair categories:Repaint, Reclear, Remake, Reglaze, Fix
Every time an order gets QC'd my system inputs some data in a "Repairs" mysql table. If it passes QC, it's given a category of Great. It's structure is like this:
id | Repair | Date
5 | repaint| 2013-01-01
6 | reclear| 2013-01-01
5 | great | 2013-01-02 ...etc
I need to be able to perform analysis on what actions are happening. I'd like to know what 'paths' items are going down.
For example. What percentage of items have these categories Reclear->Repaint->Great. What percentage have Repaint->Repaint->Remake->Great (every item should eventually end with 'Great)
I'm kind of stuck on where to start in figuring out how to analyze this.
Should I be keeping track of the repair number in the table? If I did that then maybe I could use a self join to select orders where repairnum=1 AND repair=Repaint joined with repairnum=2 AND repair='Great' This would tell me which orders went down the path Repaint->Great I'm a little hesitant to go this route because 1) I don't want to have to do a query and get the repairnumber before I insert a new row into the table and 2) It seems like I'd have to have some pretty nasty querys to analyze items that have 5 or 6 (or more) repairs.
Perhaps someone can point me in the right direction?
My app is in php and mysql.
You don't need a separate "repair number", because you have the date when each repair was made, so can order by that (assuming you store time as well if more than one repair can be made in a day).
The "path" for an item is the list of its repairs, in order of date. If you just say SELECT repair FROM repairs WHERE id=5 ORDER BY date ASC you'll get them as rows.
The trick is to turn these into a single value representing the whole path, using GROUP_CONCAT - SELECT GROUP_CONCAT(repair ORDER BY date ASC SEPARATOR '->') FROM repairs WHERE id=5
Once you have that, you can run that for all products in the DB using a GROUP BY, and then look for patterns in it with HAVING:
SELECT
id,
GROUP_CONCAT(repair ORDER BY date ASC SEPARATOR '->') as path
FROM
repairs
GROUP BY
id
HAVING
path = 'Repaint->Repaint->Remake->Great'
Note that I don't have a copy of MySQL to try this out with, so I may have made a mistake, but the manual suggests that the above should work.
I'm coding a Classified Ads web application. The application has several types of Ads:
General ads(electronics, toys, pets, books...)
Real estate (houses, apartments, terrains...)
Vehicles (motocycles, cars, vans, trucks...)
Each type has several common fields (id, title, description) and also some that are exclusive to its kind:
General Ads (no exclusive fields)
Real estate (area, type-of-property...)
Vehicles (type-of-vehicle, cubic-capacity, kilometers...)
What is the most recommended approach to this situation?
A table that contains all fields and leave empty the fields that
don't apply to the current recordset.
A main table with the fields common to all Ads, and an additional table for each type of Ad that has exclusive fields.
One table for each type of Ad.
Other
I would build a solution depending on various criteria :
If you believe the table will be large in the future (a lot of ads to be published), you may want to minimize the number of JOINs for better performance => option 1. "one table with empty fields when not relevant to ad type"
Previous comment applies especially if your data storage cost is low.
If you have to query the data against certain field values (e.g. house size, car kilometers), you might avoid the solution described by phpalix (ad_type | property | value) or Andy Gee since your SQL syntax will be a nightmare, and prefer to have all your data in the same table (again).
If there are A LOT of custom fields per ad type, you might prefer to separate each ad type in their own table, for easier maintenance and data storage optimization. Then you can either JOIN or UNION to query your ads lists.
I'll add to my answer if i think of something else.
You can normalise (a table for the abstract concept and a table the the specialised one) or denormalise (a table with all the fields)
As always, the choice must be done according to the cost of each solution, reprensented by the speed of the queries (normalised model means more joins (buffer/cpu) whereas denormalised more disk reads usually because the columns are sometimes retrieved when it is not necessary) or the storage required in both cases.
All solutions are acceptable and a matter of preference, performance, complexity and design needs. The terms for what you are discussing are Table-Per-Type, Table-Per-Class and Table-Per-Hierarchy. If you google on these you are guaranteed to get a ton of Entity Framework results, but the underlying design considerations are much the same.
For flexibility I would have all the field in a separate table then allow the assigning of each field to each ad type. This would also allow you to add and remove fields easily at a later date.
Each field may have different types of data so this information should also be in a separate table.
Something like this (not very clear sorry)
Table: fields
field_id, field_type, field_name
1 1 title
2 1 price
3 2 size
4 3 description
5 1 square meters
Table: field_types
field_type_id, type
1, textbox
2, select_box
3, text_area
Table: field_data
field_data_id, ad_id, field_id, field_type_id, field_data
1 1 1 1 Cool t-shirt
2 1 2 1 5.99
3 1 3 2 L,XL,XXL,XXXL
4 1 4 3 Some description
5 2 1 1 Nice house
6 2 2 1 250000
7 2 4 3 Some description
8 2 5 1 1024sq/m
Table: ad_types
ad_type_id, ad_type_name, fields
1 general 1,2,3,4
2 real_estate 1,2,4,5
Well, store the values in columns and not in rows, so create a table and have 3 columns:
ad_type, property, value
define your properties for each type of ad and query the ad type for its fields.
Hope that helps
I'm working on a horse rating system and I need to assign values to each horse based on the value of another (already filled) field (all this is stored in a MySQL db).
Consider the following simplified example:-
A four horse race where the odds for each horse are as follows:-
Horse A - 2/1
Horse B - 3/1
Horse C - 3/1
Horse D - 5/1
As Horse A has the lowest price, I want to give it a value of 1.
However, Horse B and C have the same price and so I want to give them both 2.
Horse D has the next highest price and so I want to give it the value of 3.
When I first started to do this, I thought it would be easy but it has now reached the stage where the loops are driving me loopy. Any suggestions would be greatly appreciated.
Many thanks in advance.
In view of the response I received below from Daan then I should also add that my problem is further compounded by the fact that my table has several subsets (i.e. it contains more than one race on any given day and they need to be ranked individually).
My table is currently:-
racedate | racetime | racecourse | horsename | forecast | forecast_rate | id
The racedate for the purposes of this will always be the same. The racetime and racecourse together identify the race in question.
forecast is the price given to each horse (this has already been entered at this stage) and this is what needs to have the shared ranking done on it to be stored in forecast_rate.
id is just the unique index for each entry in the table.
This is what I have now got to (and it doesn't work... surprise...)
$testdude=mysql_query("SELECT DISTINCT racecourse,racetime FROM picking") or die(mysql_error());
while($rih=mysql_fetch_array($testdude)){
$testdude1=mysql_query("SELECT s1.forecast, s1.horsename, COUNT(DISTINCT s2.forecast) AS rank FROM picking s1 JOIN picking s2 ON (s1.forecast <= s2.forecast) GROUP BY s1.horsename;");
while($rih1=mysql_fetch_array($testdude1)){
mysql_query("UPDATE picking SET forecast_rate='$testdude1[rank]' where horsename='$testdude1[horsename]'") or die(mysql_error());
}
}
This is called shared ranking and it's easiest to do this in MySQL. Take a look at this tutorial and see whether you can get that to work. If not, please provide more details about your table lay-out, and I'll get you a tailored example :)