I think the solution to this problem should be easy, but I can't find a good way around it.
I'm working with UK postcodes. My reference db looks like this:
+----+----------+----------+
| ID | postcode | leadtime |
+----+----------+----------+
| 1 | AB10 | 1 |
| 2 | AB11 | 2 |
| 3 | B7 | 3 |
| 4 | SE16WD | 1 |
+----+----------+----------+
The value in this table only represents the first half of a full UK postcode, but that's all we need to check against.
Now, the user has a form where they can type their FULL postcode to check what the lead time will be (the full postcode is then use as part of the delivery address).
Uk postcodes can have different length and you can type them with or without spaces between the first and the second half. Right now I have some PHP code that would basically take whatever was typed by the user and try to run it through all the different layout possibility, but it doesn't always work.
I'd like to find a way to do so in MySQL. I've started playing around with
SELECT leadtime FROM myTable WHERE postcode LIKE '$postcode%'
But this only works for the first few digits. As soon as the user types the entire postcode, this query won't find anything in the table.
I cannot for the life of me, find a way to match the two values!!
I'm sure I'm missing something really basic here!
Thanks a lot for your time and help with this.
EDITED the MySQL table to better reflect the variety in reference postcodes to check against.
SELECT * FROM user;
+---------+--------+
| user_id | user |
+---------+--------+
| 3 | George |
| 1 | John |
| 2 | Paul |
| 4 | Ringo |
+---------+--------+
SELECT * FROM user WHERE 'Ringo Starr' LIKE CONCAT(user,'%');
+---------+-------+
| user_id | user |
+---------+-------+
| 4 | Ringo |
+---------+-------+
I see no other way around than stripping the postcode from whitespaces and comparing your DB 'postcode' field with a 4 characters substring of that postcode.
You can always:
make a "broader" selection by using substr($postcode, 0,2);
then loop through the results and trim off the alphabetic characters from the beginning of each result using regex;
then parse the numeric string to number using intval();
and finally make a number-range comparison to narrow down the result.
The above technique may be a bit more complex, but you will have more control over the final results.
If you need a code example of how to achieve this, kindly comment and I will update the answer.
try like this
replace space by wildcard
select USERNAME FROM LOGIN_USERS WHERE USERNAME LIKE CONCAT('%',REPLACE('user_inPut',' ','%'),'%');
Related
I've got a search puzzle I need to solve, but my skillset is minimal, so apologies if I don't explain this well. To try and demonstrate the problem, here is an example of the data in two database columns:
| Start address | End address |
-----------------------------------------------
1 | Essex | Moortown, Leeds |
2 | Place A, London | Place B, Manchester |
3 | Townsville, Essex | Leeds Town Hall |
4 | Essex Trading Estate | Another Leeds Estate |
5 | Somewhere, Devon | Yeoville |
6 | ... | ... |
If, for example, a user submits "21 Some Street, Essex" and "Leeds some place" in the corresponding form fields, I need to search the MySQL database and pull back the top X number of best matches, which in this example would be rows 1, 3 and 4, as they all contain Essex in the first column and Leeds in the second.
I can see that PHP has two functions similar_text() and levenshtein(), which may help with this, but I'm not sure which is the more appropriate for this sort of part matching and how to get the most accurate search results. I've not found anything similar within MySQL.
Is anybody with experience of this able to give me any pointers, please?
Cheers
Andy
You can use simple like function to get the required search output. To make overcome the case sensitive use lower or upper.
select start_address,end_address from table where lower(start_address) like '%urfirststring%'
and lower(end_address) like '%ursecondstring%'
Pass your search strings also in lower .
I have four tables. The first describing a mix of items. The second is a linking table between the mix, and the items. The third is the item table, and the fourth holds lot information - lot number, and when that lot starts being used.
mix
mixID | mixName
----------------
1 | Foxtrot
2 | Romeo
mixLink
mixID | itemID
----------------
1 | 1
1 | 2
1 | 3
item
itemID| itemName
----------------
1 | square
2 | triangle
3 | hexagon
itemLots
itemID| lotNo | startDate
-------------------------
1 | 22/5/3| 22/07/16
2 | 03/5 | 25/07/16
2 | 04/19 | 12/08/16
3 | 15/0 | 05/08/16
Now, I need to be able to fetch the information from the database, which details all the items from a mix, as well as the most recently used lot number, something like this:
itemName | lotNo
----------------
square | 22/5/3
triangle | 04/19
hexagon | 15/0
I've tried a dozen different mixes of joins, group by's, maxes, subqueries, and havings; all to no avail. Any help would be much appreciated, I've been pulling my hair out for hours, and I feel like my fingernails are just scraping at the solution!
This will give you the result you're after and will perform pretty well if you have your indexes done properly. I'm not sure how you're meaning to reference mix as it's not apparent in your sample output but I've included it in the WHERE clause so hopefully you can understand where you would use it.
SELECT i.itemName
, (SELECT il.lotNo FROM itemLots il
WHERE il.itemID=i.itemID
ORDER BY il.startDate desc
LIMIT 1) as lotNo
FROM item i
JOIN mixLink ml ON ml.itemID=i.itemID
JOIN mix m ON m.mixID=ml.mixID
WHERE m.mixName="Foxtrot";
I've got a list of ID numbers, (ex: 100230, 123890, 342098...). I've also got a table, with one column devoted to ID numbers:
thisID | name | dateBirth | State
----------------------------------
192465 | Fred | 94-12-06 | OR
197586 | Alex | 78-04-26 | NM
197586 | Alex | 78-04-26 | CA
178546 | Sam | 65-12-01 | NY
112354 | Katy | 89-06-22 | CO
...
I need to return any rows with 'thisID' that matches any of the items in the list I've got. Also, note that sometimes there may be multiple rows with the same ID that match an item in the list... in that case, all matching records should be returned.
I've looked around, and seen some recommendations to use arrays or temporary tables or something, but nothing definitive. How should I do this?
You can use the IN sql syntax for this, if I understand you correctly.
SELECT * FROM tablename
WHERE thisID IN (100230, 123890, 342098);
You can do like this:
select * from [table_name] where thisID in ([your IDs]);
It will return all the rows that match the given IDs.
See the SQLFiddle Demo
I have a comma delimited list that im storing in a varchar field in a mysql table.
Is it possible to add and remove values from the list directly using sql queries? Or do I have to take the data out of the table, manipulate in PHP and replace it back into mysql?
There is no way to do it in InnoDB and MyIsam engines in mysql. Might be in other engines (check CSV engine).
You can do it in a stored procedure, but, not recommended.
What you should do to solve such an issue is to refactor your code and normalize your DB =>
original table
T1: id | data | some_other_data
1 | gg,jj,ss,ee,tt,hh | abanibi
To become:
T1: id | some_other_data
1 | abanibi
T2: id | t1_id | data_piece
1 | 1 | gg
2 | 1 | jj
3 | 1 | ss
4 | 1 | ee
5 | 1 | tt
6 | 1 | hh
and if data_piece is a constant value in the system which is reused a lot, you need to add there a lookup table too.
I know it looks more work, but then it will save you issues like you have now, which take much more time to solve.
If i wants count the matching words in a rows of two tables, with milions of rows, sample:
Table posts, sample:
+----+---------+-----------------------------+
| ID | ID_user | text |
+----+---------+-----------------------------+
| 1 | bruno | michael jackson is dead |
| 2 | thomasi | michael j. moonwalk is dead |
| 3 | userts | michael jackson lives |
+----+---------+-----------------------------+
i want query the words most repeated on the table, limit top 10, the result may be this:
+-------+------------+
| count | word |
+-------+------------+
| 3 | michael |
| 2 | dead |
| 2 | jackson |
| 1 | j. |
| 1 | lives |
| 1 | moonwalk |
+-------+------------+
but i want search only words that repeat more of 10 times, in this case noone word is appear, but if criteria for repetead words is 2, will display only 'michael' and 'dead', but ignore 'is' because i dont want words with less 2 chars of lenght, and the words that a phrase, then i need apear this:
+-------+-----------------+
| count | word |
+-------+-----------------+
| 2 | michael jackson |
| 2 | dead |
+-------+-----------------+
i need a code in mysql that replies the "trending topics" of twitter for posts of my site.
What you're looking for is term extraction, which isn't provided natively within MySQL.
Some other platforms provide that function, but it's considered an enterprise feature, so you'll have to pay through the nose for it.
Alternatively, you can use something like Yahoo!'s Term Extraction API.
Here is a blog post that talks about using Yahoo!'s service from PHP5.
break the sentence up on insert, filter the words against a blacklist, store distinct words with a count (or probably with references). count using count() :)
this would generate a lot of data tough, and i don't know what the speed and storage implications are.