How can I work this REPLACE statement I'm using in the following, into my SELECT statement below ? The update works perfectly, but need the same code in the SELECT.
$sql1 = ("UPDATE $table SET notes=replace(REPLACE(notes,CHAR(13),' '),CHAR(10),' ') WHERE year='$year'");
$sql2 = "SELECT * FROM $table WHERE SUBSTR(week_start_date,-4)=$startDate AND week_num = '$week' AND archived!='yes' ORDER BY fn,ln";
Thanks for any assistance.
If you have data in your table that has CRLF that you want to REPLACE with ' ', you can't use the SELECT * notation - you have to tell it which column you want to replace the characters in. You'll have to do something like this:
$sql2 = "SELECT REPLACE(REPLACE(notes, CHAR(13), ' '), CHAR(10), ' ') as fixed_notes FROM $table ...`
In general, it's best to avoid using SELECT *, and always to specify the columns you want (as well as any scalar functions you want to run on said columns) explicitly. This way, if the table definition adds more columns, you don't start getting data you never intended to process; and if a column gets dropped, you'll know that was the cause rather than something else in your presentation layer. It also means that it'll be possible to manipulate the individual columns in the statement where appropriate.
If you can live with these limitations, and you don't mind having the column appear twice, you could do this:
$sql2 = "SELECT *, REPLACE(REPLACE(notes, CHAR(13), ' '), CHAR(10), ' ') as fixed_notes FROM $table ...`
Related
I want to have result of my query as it was before I replaced db connection using PDO. How can I get the query as i t was before I implemented PDO?
This is my query:
$query =
"SELECT
`id_affirmation`,
`affirmation`,
`author`,
`user_rate`,
am.date,
am.time,
hua.date,
hua.time
FROM `affirmation_male` am
JOIN `history_user_affirmation` hua ON am.id_affirmation = ua.affirmation_id
WHERE hua.user_id = '" . $id_user . "'
ORDER BY
STR_TO_DATE(hua.date, '%d-%m-%Y') DESC,
hua.time DESC";
For some reason the result of query when I use PDO is i got date from affirmation_male. Do you know why?
Your query returns two columns that have the same name, hence PDO gets lost when it fetches the results; since each records is represented as an associative array, duplicate keys generate ambiguity (only one key will be retained).
You would need to alias those columns to remove ambiguity:
$query =
"SELECT
`id_affirmation`,
`affirmation`,
`author`,
`user_rate`,
am.date am_date,
am.time am_time,
hua.date AS hua_date,
hua.time AS hua_time
FROM `affirmation_male` am
JOIN `history_user_affirmation` hua ON am.id_affirmation = hua.affirmation_id
WHERE hua.user_id = '" . $id_user . "'
ORDER BY
STR_TO_DATE(hua.date, '%d-%m-%Y') DESC,
hua.time DESC";
Notes:
it would also be a good idea to prefix the first columns in the query with the alias of the table they belong to, as this makes the query more readable (and will avoid conflicts if ever these columns names were available in more than one table coming into play in the query)
you could remove backticks to make the query more readable, as the column and table names that you are quoting do not seem to contain any special characters
I have my database field named tag_info in it I will have data that appears like so:
arm leg head forearm foot
Tags are separated by spaces. (not sure if that is the best way so I am open to suggestions)
Now I need to write a query that will return all the rows that have specific tags in the tag_info field. But the tags I am looking for do not all need to be present just at least one of them does.
$find_tags = array("arm,"leg");
$query = "SELECT * FROM mydatabase WHERE tag_info = '$find_tags'
Is this possible?
You should probably change your database schema around first. Instead of storing tags separated by spaces.
Could you show me the schema (column names) for your table. I think this is a case where you should be having two tables. A separate table just for tags.
That's not a good way to do tagging. You should have a tags table (id, name), yourdatabase_tags (yourdatabaserecord_id, tag_id) so you can associate a record in yourdatabase table to a tag in tags table.
So when you have a list of tags, do a query to get their ids, then query yourdatabase_tags to get the record_ids that have that tag_ids, then query yourdatabase for the records. Or you can combine them into one query (That's an exercise left for the readers :)) )
Mysql syntax does not work that way
here what will work.
$query = "SELECT * FROM mydatabase
WHERE tag_info = '".$find_tags[0]."' OR tag_info = '".$find_tags[1]."'";
In your case since the tags are all in one field you can use a wild card: %
$query = "SELECT * FROM mydatabase
WHERE tag_info LIKE '%".$find_tags[0]."%' OR tag_info LIKE '%".$find_tags[1]."%'";
Query with where tag_info like '%arm%' or tag_info like '%leg%'
but this will be quite inefficient, better to store tags seperately one tag per row, have an index on it.
It's not possible to write a query like that because you will have to dynamically change the amount of OR statements in WHERE blah OR blah. One way to do this would be to grab all the data from the database into a PHP Array. Once in the array you can programatically search through the results and eliminate the ones that do not match.
That is if you want to search for different tags, if you only need a specific query for
$find_tags = array("arm,"leg"); the other answers will work.
you can try below query.
$query = "SELECT * FROM mydatabase WHERE tag_info IN ('$find_tags');
if you are using a table name and field name correct then this may be needful to you.
Thanks.
$keywords = array("arm", "leg");
$length = count($keywords);
$searchCriteria = '';
for($i = 0; $i < $length; $i++)
{
$searchCriteria = $searchCriteria . "tag_info like '%" . $keywords[$i] . "%'";
if( ($i+1) < $length)
$searchCriteria = $searchCriteria . " OR ";
}
$query = "SELECT * FROM mydatabase
WHERE $searchCriteria";
You may need to add some additional checking to ensure that you don't run into error if the array containing the tags is empty.
The more correct approach would be to have a tag table with the availeble tags and a link table between tag_info and tag_table.
But here is a solution with a query
$query = "SELECT * FROM mydatabase WHERE ";
foreach($find_tags as $tag)
{
$query .= "tag_field LIKE %$tag% OR ";
}
$query = substr($query, 0, strlen($query) - 3);
Not tested!!
Sure, use a LIKE in the WHERE clause instead of =.
SELECT * FROM mydatabase WHERE tag_info LIKE '% foot %' or tag_info LIKE '% leg %'
your query should look something like
SELECT * FROM mydatabase WHERE tag_info = 'arm' OR tag_info = 'leg'
You could also use the MySQL IN clause:
SELECT * FROM mydatabase WHERE tag_info IN ('arm', 'leg')
This way is easier to build the query string
Edit
I just saw that you are holding the tags serialized in the DB. Now, that is definitely not good because you are destroying the concept of the structured data.
You should create a table called tags and hold each tag on its own row. Than create another pivot table between the table you wish to tag (the one that holds the serialized tags now) and the tags table.
The pivot table can hold just 2 fields - main_table_id and tag_id - this way, you will be able to query your DB with a single join like:
SELECT t.* FROM tags t
INNER JOIN pivot_table pt ON pt.tag_id = t.id
INNER JOIN main_table mt ON mt.id = pt.main_table_id
WHERE tag IN ('arm', 'leg')
I have this query:
"SELECT * FROM informations WHERE ". $id ." IN (ids)"
It only works if $id is the first value from ids... in ids values are "1,2,3,4,5".
Is there a way for it to work with the rest of the ids?
Would this work for you?
"SELECT *
FROM Informations
WHERE ids LIKE \"" . $id . ", %\" -- try to match against the first value in ids
OR ids LIKE \"%," . $id . ",%\" -- try to match against a value in ids that is neither the first nor the last value
OR ids LIKE \"%," .$id . "\" -- try to match against the last value found in ids"
If ids is a field containing comma-delimited values, then your query is like:
SELECT * FROM `informations` WHERE 3 IN ("1,2,3,4,5")
Instead of what it should be:
SELECT * FROM `informations` WHERE 3 IN (1,2,3,4,5)
There is no automatic tokenisation (splitting on ,) performed; the one value of ids is not automatically converted into a list for you such that IN can work.
Unfortunately your table design has been your undoing here. Can you split the IDs into a separate table using the principle of database normalisation?
Then your query might look like:
SELECT * FROM `informations` WHERE 3 IN (
SELECT `id`
FROM `ids`
WHERE `informations`.`id` = `ids`.`information_id`
)
BTW, "information" is a non-countable noun and, as such, "informations" is wrong.
Update (thanks for the idea, a1ex07!)
Although this is hackery and I still suggest fixing your table layout, I'll be kind and suggest a quick fix.
Willempie was close with:
$query = 'SELECT *
FROM `informations`
WHERE `ids` LIKE "%' . $id . '%"';
Unfortunately, a wildcard match isn't quite powerful enough. Consider if ids is like "1,6,9,12,35,4" and $id is like 3. You get a false positive. The LIKE statement needs to be aware of the commas.
You can add multiple cases:
$query = 'SELECT *
FROM `informations`
WHERE `ids` LIKE "%,' . $id . ',%"
OR `ids` LIKE "%,' . $id . '"
OR `ids` LIKE "' . $id . ',%"';
Or, for brevity, you can work around this with regular expressions:
$query = 'SELECT *
FROM `informations`
WHERE `ids` REGEXP "(^|,)' . $id . '(,|$)"';
For any $id you wish to find, before it must be the start of ids (^) or a comma; after it must be a comma or the end of ids ($). This ensures that $id must be found as a whole, comma-delimited token.
It's a little like "Whole Word Only" in word processor searches, but with commas separating "words" instead of spaces.
Update 2
Another way uses FIND_IN_SET, which performs a search within a comma-delimited string:
$query = 'SELECT *
FROM `informations`
WHERE FIND_IN_SET("' . $id . '", `ids`)';
Your query is technically correct but the values for 'ids' are not.
You should enclose the values of ids within single quotes. If I were to write the code without using ids, it would be like this:
"SELECT * FROM informations WHERE ". $id ." IN ('1','2','3','4','5')"
More info on this rule here: http://dev.mysql.com/doc/refman/5.1/en/comparison-operators.html#function_in
I'm not sure what you are trying to achieve. If ids is a column in informations your code is just a weird way to express "SELECT * FROM informations WHERE ids = ". $id "; If it is a string, I don't see why you need WHERE at all : expression $id in (1,2,3,4,5) is constant, it doesn't require interaction with database; in any case you either grab all rows from informations or none.
UPDATE
Another suggestion :maybe ids is a string field in informations that contains "1,2,3,4,5". In this case you cannot get expected results by using WHERE ... IN. You need to use REGEXP to check if string contains your number.
It has to be column name then IN (comma separated values here).
SELECT column_name(s)
FROM table_name
WHERE column_name IN (value1,value2,...)
You did an error in sql syntax.
This is the correct syntax
"SELECT * FROM informations WHERE ids IN (". $id .")";
Ok, normally I know you would do something like this if you knew the array values (1,2,3 in this case):
SELECT * WHERE id IN (1,2,3)
But I don't know the array value, I just know the value I want to find is 'stored' in the array:
SELECT * WHERE 3 IN (ids) // Where 'ids' is an array of values 1,2,3
Which doesn't work. Is there another way to do this?
Use the FIND_IN_SET function:
SELECT t.*
FROM YOUR_TABLE t
WHERE FIND_IN_SET(3, t.ids) > 0
By the time the query gets to SQL you have to have already expanded the list. The easy way of doing this, if you're using IDs from some internal, trusted data source, where you can be 100% certain they're integers (e.g., if you selected them from your database earlier) is this:
$sql = 'SELECT * WHERE id IN (' . implode(',', $ids) . ')';
If your data are coming from the user, though, you'll need to ensure you're getting only integer values, perhaps most easily like so:
$sql = 'SELECT * WHERE id IN (' . implode(',', array_map('intval', $ids)) . ')';
If the array element is not integer you can use something like below :
$skus = array('LDRES10','LDRES12','LDRES11'); //sample data
if(!empty($skus)){
$sql = "SELECT * FROM `products` WHERE `prodCode` IN ('" . implode("','", $skus) . "') "
}
If you use the FIND_IN_SET function:
FIND_IN_SET(a, columnname) yields all the records that have "a" in them, alone or with others
AND
FIND_IN_SET(columnname, a) yields only the records that have "a" in them alone, NOT the ones with the others
So if record1 is (a,b,c) and record2 is (a)
FIND_IN_SET(columnname, a) yields only record2 whereas FIND_IN_SET(a, columnname) yields both records.
I created a user defined sql query that doesn't work. Users are supposed to be able to enter search strings in an input field, submit then see the results of their search but everytime I enter a search for something that I know is in the database I get the unknown column "x" in "where clause" error message.
Would you please help me fix the problem? Here's the code that i wrote for it so far...
...
mysql_select_db("mydb", $c);
$search = $_POST['search'];
$rslt = mysql_query("SELECT * FROM mytable
WHERE 'mycolumn' RLIKE $search");
while($row = mysql_fetch_array($rslt))
{
echo $row['myrow'];
echo "<br />";
}
if (!$row)
{
die('uh oh: ' . mysql_error());
}
?>
Change the code to this:
1) Convert quotes to backticks around column name.
2) Surround $search with single qoutes to make it a string.
$rslt = mysql_query("SELECT * FROM mytable WHERE `mycolumn` RLIKE '{$search}'");
This helps for sure
just change the variable $search to be read as a string i.e $search
so it will be like this
$rslt = mysql_query("SELECT * FROM mytable WHERE mycolumn RLIKE '$search'");
I would like to add a few about security and performance.
It is unsafe to put user input (any GET, POST or cookie data) directly into the SQL query. This is a serious security issue called SQL injection. To avoid it, use mysql_real_escape_string() function.
Also, SELECT * FROM mytable ... is not a good practice. It is recommended to explicitly list all the columns needed even if they all are:
SELECT col1, col2, col3, col4, col5 FROM mytable ...