I have a tricky (well for me it is) question about getting info from 2 different tables.
I have an array, like this:
$abc=$_COOKIE['cookie'];
$comma_separated = implode(",", $abc);
Now, the array will be a CSV list of ID's that need to match ID's from the "Specials" table. In the "Specials" table there is a column called Contract Name. This Contract Name column needs to match a column of the same name, each unique, in the Products table, and display the information contained therein.
My currenty MySQL query looks like this:
$query= "SELECT specials.id,
specials.product_name,
specials.contract_name,
specials.included_value AS inc_val,
specials.image_url,
specials.contract_monthly,
specials.outlet,
products.package,
products.bundled,
products.included_value
FROM specials,
product
WHERE `id` IN ('.$comma_separated.')
AND specials.contract_name = `products.package`";
What happens is... that nothing happens. I've tried wrapping my brain around some of the JOIN tutorials but no luck.
So basically I'd like to display a list of current specials, along with the package info, which is contained in a different table. I've tried wrapping my brain around some of the JOIN tutorials but no luck.
To my knowledge I'm crap at explaining things properly, so please do shout if I can shed any more light on this conundrum.
Thanks! :)
To even start to get this to work, your $query string is going to have to be a valid query. Ordinarily, to troubleshoot this kind of problem, you do echo $query; somewhere along the way to see if it is valid. You then might even paste the query's textinto a standalone MySQL client (phpMyAdmin, or maybe HeidiSQL or something) to see what you get.
Looking at this line:
WHERE `id` IN ('.$comma_separated.') /* wrong! */
it looks like it needs to read
WHERE `id` IN (".$comma_separated.")
because you're using double quotes to surround your fragments of SQL text. Also, you might want to use
WHERE `specials`.`id` IN (".$comma_separated.")
just because some other tables might contain id columns and then your search clause will be ambiguous.
Related
I have a table with some submissions, this table has a tags field, and I need to search in it.
The data is saved in JSON format in the table, like this: ["basic","example","html","chart"]
I'm trying to find a way to search all rows in the tags fields, but not sure how it can be done the best way when it is in this format.
The user submits an tag to search, like: html, then I need to search all rows for that tag, without to much overhead.
I know most people use to say: what have you tried yourself?
- well, nothing. As I have no clue how to do this, I know how to search in sql and all that. but never tried it in this logic.
There is no "best way" to search in this format. There is no way at all.
No wonder you have no clue how to do that. I'll tell you more - no one knows it either. Tags should never be stored in json format. It is like as if you built a car, placing wheels on the roof. And then come asking, how to drive it.
You have to learn database basics first. And then create your tables proper way. making a separate table for tags. Storing each on a separate row. After that you will be able to search a tag usual way, using JOIN query to attach the corresponding records to the result.
$sql = "SELECT a.* FROM articles a, tags t WHERE aid=a.id AND tag=?";
$stmt = $pdo->prepare($sql);
$stmt->execute(array($tag));
$data = $stmt->fetchAll();
You should create another table tag with fields name, post_id.
I believe that is the best solution to do a search feature.
If you do not have permission to create database table. It depends on how many posts you have. a few? hundreds or even more? If there is not a huge rows of your post table. You can fetch all of them and decode to PHP Array and then use string comparison.
Or maybe, you can give up the database way, just handling with a cache file. We're only need to write cache if user create/modify a post.
But you also can use the unreliable way, using like operator in mysql.
You should take a look at the MySQL fulltext index.
Take a look in the manual and this Zend Developer article
But you shouldn't use fulltext searching for many columns.
In one of my projects I worked around it by concatenating to be searched columns in a TEXT column and apply to the fulltext index on it.
It's simple you can try using like query
SELECT * FROM `post` WHERE `tags` LIKE '%html%';
In PHP Variable:
$tag = "html";
$query = mysql_query("SELECT * FROM `post` WHERE `tags` LIKE '%'.$tag.'%'");
I have been trying to create a database for fun to get a better understanding of databases and using PHP to query them for a website I'm messing around with. Pretty much I have one database with 4 tables when a user enters a search term in a PHP search box my code searches the database for any entries containing the search term. Now I can easily get my code to search individual tables, but I cannot seem to get it to search all 4 tables and display the results on the same page.
info: making a database for skyrim
Table names: classes, powers, skills, shouts
column names: name, information
Here is a snippet of the code I have that works so far:
$raw_results = mysql_query("
SELECT *
FROM `xaviorin_skyrim`.`shouts` , `xaviorin_skyrim`.`classes`
WHERE (CONVERT(`UID` USING utf8) LIKE '%".$query."%' OR
CONVERT(`Name` USING utf8) LIKE '%".$query."%' OR
CONVERT(`Information` USING utf8) LIKE '%".$query."%')
") or die(mysql_error());`
Literally all I thought I would need to do is change the table name from "shouts" to say "classes" in a new raw_results line of code but that didn't work. I have attempted unions and joins and either keep screwing them up or just don't understand how to properly format them.
echo "<p><h3>".$results['Name']."</h3>".$results['Information']."</p>";
The code above this text is what displays the results on the page on my website... it works but I don't know how to combine the information from all 4 tables into one page. If I'm going about this in the wrong way and anyone can point me in the right direction I would GREATLY appreciate it... I've been trying to research the problem without finding a proper answer for near a month now.
The problem with your approach is that relational databases do a cross join when there are several query results from two different tables. So basically every match in one table will be combined with every match from the second table. When you have 3 entries in the first and 4 in the second table, you will get 3 * 4 = 12 entries in your query result. If you add more tables, you get even more results. You want to do a full text search in several tables that are totally unrelated, thus creating some kind of non-existing relation via cross joining them will not be useful.
What you actually want to do is a UNION ALL (UNION is slower because it prunes duplicates) of several queries:
SELECT name, information, 'shouts' AS tablename FROM shouts WHERE ...
UNION ALL
SELECT name, information, 'classes' AS tablename FROM classes WHERE ...
This will do search queries on every single table and then place the results in a single result. Also note that I added a third column to each query to ensure that the originating table is not lost after merging the results.
Unless you need to do some sorting afterwards, I would suggest that you do all statements separately. Combining them this way will most likely make the post-processing more complex. And several single queries will also be faster than one big query with UNION statements.
And as I mentioned in the comments: Don't use mysql_* functions!
I have a PHP interface with a keyword search, working off a DB(MySQL) which has a Keywords field.
The way in which the keywords field is set up is as follows, it is a varchar with all the words formatted as shown below...
the, there, theyre, their, thermal etc...
if i want to just return the exact word 'the' from the search how would this be achieved?
I have tried using 'the%' and '%the' in the PHP and it fails to work by not returning all of the rows where the keyword appears in.
is there a better (more accurate) way to go about this?
Thanks
If you want to select the rows that have exactly the keyword the:
SELECT * FROM table WHERE keyword='the'
If you want to select the rows that have the keyword the anywhere in them:
SELECT * FROM table WHERE keyword LIKE '%the%'
If you want to select the rows that start with the keyword the:
SELECT * FROM table WHERE keyword LIKE 'the%'
If you want to select the rows that end with the keyword the:
SELECT * FROM table WHERE keyword LIKE '%the'
Try this
SELECT * FROM tablename
WHERE fieldname REGEXP '[[:<:]]test[[:>:]]'
[[:<:]] and [[:>:]] are markers for word boundaries.
MySQL Regular Expressions
if you also search for the commas, you can be sure you are getting the whole word.
where keywordField like '%, the, %'
or keywordField like '%, the'
or keywordField like 'the, %'
maybe I didn't understand the question properly... but If you want all the words where 'the' appears, a LIKE '%word%' should work.
If the DB of words is HUGE MySQL may fail to retrieve some of the words, that can be solved in 2 ways...
1- get a DB that support bigger sizes (not many ppl would chose this one tho). For example SQL Server has a 'CONTAINS' function that works better than LIKE '%word%'.
2- use a external search tool that uses inverted index search. I used Sphinx for a project and it works quite good. This is better if you rarely UPDATE the rows of the data you want to search from, which should be the case.
Sphinx for example would generate a file from your MySQL table and use this file to solve the search (it's very fast), this file should be re-indexed everytime you do a insert or update on the table, making it a much better solution if you rarely update or insert new rows.
It looks like you have a one to many relationship going on within a column. It might be better to create a separate table for keywords with a row for each keyword and a foreign key to whatever it is you're searching on.
Doing like '%???%' is generally a bad idea because the DB can't make use of an index so it will scan the whole table. Whether this matters will depend on the size of data you're working with but its worth considering up front. The single best way to help DB performance is in the initial table design. This can be tricky to change later.
Ok so I have looked up several ways of getting this done, and none of them work for me, let me give you a few details on why the methods I have tried don't work.
I have tried SUBSTRING_INDEX and as most of us know it only "splits" based on the number of delimiters there are in the string, and well it isn't the same amount for all of the rows, so that is a no go, I also tried the method found here http://blog.fedecarg.com/2009/02/22/mysql-split-string-function/
Again I believe that it goes based on the number of delimiters in your query.
I have searched and searched for a way to get this done, and I just can't find a way to get it working. I am still a bit of a newbie to PHP so this could be a simple fix and I am just overlooking it somehow, but that I am not sure of.
Here is what I am working with;
This is the sql query
$sql = "SELECT * FROM offers WHERE type='$type' and country='$membercountry' LIMIT $start, $limit";
$result = mysql_query($sql);
country is the column that has my comma delimited string. Some rows simply just have something like US while others have US,AU,CA,GB
The reason I am needing to split these is because the page that actually displays the offers checks to see if the users country matches the offers country, and it is obviously going to not match when it is reading it as a whole long string, Which means those offers won't show up for the user.
I talked to a friend of mine and he said to use explode(), but I am pretty sure you cannot use explode() in a sql query.
I know I probably haven't explained this as well as I could have, I have been working on this project all night so I am a bit tired.
Also as a note, I know that I could just make it to where there are multiple rows for each offer supplying the different country, but some of these offers allow all countries to do them, that would mean that for 1 offer I would have like 243 rows, and that would make me feel like I was just being sloppy!
If anyone could give me a push in the right direction I would be greatly appreciative!
Thanks, Casey
Bit of an odd/bad data design: multiple countries in a column named country. That aside, you could maybe do something with FIND_IN_SET().
mysql> SELECT * FROM offers WHERE FIND_IN_SET('CA', country);
Performance wise .. it's not going to be great but I hope you can select on other fields using a good index.
Something like this may work out:
$sql = "SELECT * FROM offers WHERE type='$type' and country LIKE '%$membercountry%' LIMIT $start, $limit";
Currently, I have a log file of messages in one table in a MySQL database. Among some other stuff, it contains the sender id, and the message itself. I want to make a way to display the log on a website.
I have a separate table that contains the sender ids and the name of the person (which is what I actually want to display).
Are there any better ways than simply running another query? While that would work, that's pretty expensive as it requires a new query for every entry. Ideally, I'd like something that would map the id --> name in an array, but I can only find things that will put everything from one row into an array (aka, horizontally), but I need entries "vertically".
I'm using PHP by the way...
Thanks!
Kevin
Learn about JOIN statements. This is exactly what you need.
I believe you are looking for something like this:
SELECT `name`, `message` FROM `msgtable` INNER JOIN `sendertable` USING(`sender_id`)