I use my SQL as backend for my project, and I need to get all record from database where some part of inputted string is available in database string like:
table = seller
id company_name seller_name
1 companyname1 seller1
2 companyname2 seller2
3 companyname3 seller3
4 companyname4 seller4
Given string is 1105 companyname1 is outstanding
So i need to get id = 1 for a given string if it is possible with laravel or MySQL then please help me.
You can construct a query using like:
where $YourString like concat('%', companyname, '%')
Note: There are situations where one company name might be sufficiently like another ("company1" and "company10"). If this is an issue, regular expressions might help.
First, you have to convert that string to an array.
$str = "1105 companyname1 is outstanding";
$str = explode(' ' , $str);
$results = Seller::whereIn('company_name' , $str)->get();
Note:
As you are converting random strings to an array, there will be a mistake where the user input some more spaces.
Let say the user input a string like $str = "1105 companyname1 is outstanding"; this will create some more elements. Like
array(
0 => '1104',
1 => '',
2 => 'companyname1',
3 => 'is',
4 => 'outstanding'
)
So, to avoid that, I have to recommend you to split out some more spaces. You can do by
$str = preg_split('/\s+/', $string, -1, PREG_SPLIT_NO_EMPTY);
Related
I have code for my filter. It worked well until I add new product in my database. I found the problem, but dont know what to do with that.
I have parameters "alc_min" and "alc_max" in my filter. I get these from crawling all products. After I send this filter, I fire this code:
$meta_query = array();
$b = "alc_min";
$c = "alc_max";
if (isset ( $data [$b] ) && isset ( $data [$c] )) {
$compare = "BETWEEN";
$a = array (
'key' => "alc",
'value' => array (
$data [$b],
$data [$c]
),
'compare' => $compare
);
array_push ( $meta_query, $a );
}
$items = new WP_Query ( array (
'post_type' => $type,
'posts_per_page' => $posts_per_page,
'order' => $order,
'meta_key' => $orderkey,
'orderby' => $orderby,
'post_status' => 'publish',
'meta_query' => $meta_query,
'paged' => $paged
) );
Until now, it worked well. No I add new product with "alc" <10 and I found, that if I have "alc_min" and "alc_max" <10 or >10, it is ok. But if "alc_min" is <10 and "alc_max" >10 I get no results at all.
Does anyone any idea what to check or fix?
After the clarification, I've suspected that the reason why selecting "alc_min" = 7 and "alc_max" = 13 doesn't yield any result is because of the column datatype. Consider this example:
CREATE TABLE table1 (
alc VARCHAR(50));
INSERT INTO table1 VALUES
('7'),
('9'),
('11'),
('13');
The table above is created with alc column datatype as VARCHAR instead of INTEGER (or numeric datatype). I've tested that running either one of the query below:
SELECT * FROM table1 WHERE alc BETWEEN '7' AND '9';
SELECT * FROM table1 WHERE alc BETWEEN '11' AND '13';
will return the expected result. However, with this query:
SELECT * FROM table1 WHERE alc BETWEEN '7' AND '13';
yields no result. This is because the values are treated as string instead of numbers and when that happens, 1 is always smaller than 7. See below what happen you run select query with order by on the data set above:
SELECT * FROM table1 ORDER BY alc;
+-----+
| alc |
+-----+
| 11 |
| 13 |
| 7 |
| 9 |
+-----+
As you can see, since the data is treated as string (according to the column datatype), then you could imagine this in alphabetical form as the following:
+-----+--------------+
| alc | alphabetical |
+-----+--------------+
| 11 | AA |
| 13 | AC |
| 7 | G |
| 9 | I |
+-----+--------------+
So, the condition of BETWEEN '7' AND '13' becomes BETWEEN 'G' AND 'AC'; which doesn't really make sense. And if you change to BETWEEN '11' AND '9' you'll get the correct result but that made the query even more confusing and not making sense at all.
Now, I've discovered that there are at least 3 workaround/solution for this:
One of the oldest way I can think of is by adding +0 to the column in the query. I didn't find any official docs about this but I assume that doing this will change the data value to numeric in the query:
SELECT * FROM table1
WHERE alc+0 BETWEEN '7' AND '13';
This is probably the same as above is just that I'm not sure if this is version specific or not. It turns out that in my testing, if you didn't wrap the searched value in quotes, you'll get the result as if the data is numeric:
SELECT * FROM table1
WHERE alc BETWEEN 7 AND 13;
This require a change of column datatype but afterwards any of the query with or without quotes on the searched value should work:
ALTER TABLE table1 CHANGE alc alc INT;
I hope that this is true and the issue is really about column datatype. As far as I know, this is the closest thing to what your situation is that I had experience with.
Here's a fiddle for reference
For a list query I want to show how many prices there are for a specific product on a specific site.
I have found a way to do this with RawSQL, something I had never ever had to do before. Am I overlooking something?
queryset = Price.objects.all()
site_annotations = {}
for site in Site.objects.all():
site_annotations['num_prices_{}'.format(site.name)] = RawSQL(
'SELECT COUNT(id) '
'FROM `product_siteprice` '
'WHERE `product_siteprice`.`price_id` = `product_price`.`id` '
'AND site_id=%s', [site.pk]
)
queryset = queryset.annotate(**site_annotations)
edit
My models look simplified like this:
class Site(Model):
name = models.CharField(_('display name'), max_length=50)
class Price(Model):
name = models.CharField()
class SitePrice(Model):
price = models.ForeignKey(Price)
site = models.ForeignKey(Site)
Now the table I want is:
Product | Nr of prices on Site A | Nr of prices on Site B |
--------|------------------------|------------------------|
Iphone | 6 | 3 |
Xperia | 42 | 66 |
And I want to sort and filter on the number of prices, so thats why I need the annotation.
NB The name Price is a bit misleading if you don't know the rest of context, in this context it can be seen more like a Product
From what I understand, you just need to filter the prices on the related site, then get the count of the number of objects.
Price.objects.filter(site_price__site_id=site.pk).count()
Although you may just want to remove the site price model and replace it with a many to many field
I think the query that you want would look something like this:
qs = SitePrice.objects.values('price_id', 'site_id').annotate(d_count=Count('id'))
And to get the table that you want, you’d format it into a dict with something like this:
from collections import defaultdict
values = defaultdict(dict)
for x in qs:
values[ x['price_id'] ][ x['site_id'] ] = x['d_count']
To print out this table, you would use:
price_ids = list(values.keys()) # you don’t need `list` for python 2
site_ids = set()
for x in values.values():
site_ids |= set(x.keys())
site_ids = list(site_ids)
site_ids.sort()
prices = dict(Price.objects.filter(id__in=price_ids).values_list('id', 'name'))
sites = dict(Site.objects.filter(id__in=site_ids).values_list('id', 'name'))
print(' ', end='') # for python 3
# print ' ', # for python 2
for x in site_ids:
print('%-8s ' % sites[x], end='')
print('')
for x, counts in values.items():
print('%-8s ' % prices[x], end='')
for site_id in site_ids:
d_count = counts.get(site_id, 0)
print('%-8s ' % d_count, end='')
print('')
I am trying to update a MySQL database but only if a field has the value Approved.
If status is Approved then Date approved should update with the date.
Below is the code I am currently using but cannot get it to work. How to get it to work?
UPDATE my_table
SET `FieldValue`= IF(FieldName='status' AND FieldValue='Approved','".date('m/d/Y')."','')
WHERE `SubmissionId`=".$SubmissionId."
AND FieldName='Date Approved'
Sample Data
+--------+--------------+---------------+--------------+
| FormId | SubmissionId | FieldName | FieldValue |
+--------+--------------+---------------+--------------+
| 6 | 778 | status | Not Approved |
| 6 | 778 | Date Approved | |
+--------+--------------+---------------+--------------+
Use a CASE statement like below:
UPDATE my_table
SET `FieldValue` = CASE WHEN FieldName = 'status'
AND FieldValue='Approved' THEN date('m/d/Y') ELSE `FieldValue` END
WHERE `SubmissionId` = $SubmissionId;
But your query won't make sense; your FieldValue column looks like a string type column and you are trying store a date type data.
Something like this?
$db = JFactory::getDbo();
$query = $db->getQuery(true);
// Fields to update.
$fields = array(
$db->quoteName('FieldValue') . ' = ' . $date->toSql('m/d/Y'))
);
// Conditions for which records should be updated.
$conditions = array(
$db->quoteName('SubmissionId') . ' = SubmissionId',
$db->quoteName('FieldValue') . ' = ' . $db->quote('Approved')
);
$query->update($db->quoteName('#__my_table'))->set($fields)->where($conditions);
$db->setQuery($query);
$result = $db->execute();
Superficially, you should be using the raw SQL like this:
UPDATE my_table
SET FieldValue = date('m/d/Y')
WHERE SubmissionId = 778
AND FieldName = 'Date Approved'
-- AND FieldValue IS NULL -- Optional
-- AND FormId = 6 -- Optional
AND EXISTS (SELECT * FROM my_table
WHERE FieldName = 'status'
AND FieldValue = 'Approved'
AND SubmissionId = 778
-- AND FormId = 6 -- Optional
)
You might need to tart things up a little to get values embedded into the string that forms the SQL statement.
You don't mention FormID in your query; in case of doubt, you should constrain the UPDATE with the correct FormID value, twice, like you constrain the SubmissionID value twice (as shown in the comments). You might decide you only want to update the 'Date Approved' field name when it is NULL (or perhaps blank).
I note that one of the problem with this EAV design is that you lose the type-checking that a normal design gives you. You could store a date (as intended), or a pure number, or pure text, or anything else in the FieldValue column for the 'Date Approved' FieldName and there's nothing to stop that abuse happening. If you had an orthodox typed column, you could ensure that non-dates were never stored in the 'Date Approved' column.
Your UPDATE is tied to a single submission ID; so is mine. It should be possible to enhance things so that all the uninitialized 'Date Approved' columns that are approved and have not previously had the 'Date Approved' value set do in fact have it set.
I have an array of value :
words = ['foo', 'bar', 'baz']
I want autogenerate a where clause with LIKE (and not "IN").
What I do for now :
words = params[:content].split(' ').map { |w| "%#{w.strip}%" }
where = []
words.size.times do
where << 'name LIKE ?'
end
tags = Tag.where(where.join(' OR '), *words)
the correct request SQL is generate :
SELECT `tags`.* FROM `tags` WHERE (name LIKE '%foo%' OR name LIKE '%bar%' OR name LIKE '%baz%')
but it's not realy nice way...
when I want compare array values with equals, we can just do :
Tag.where(name: words)
There is a possibility to do same thing but not generate IN, but multiple OR LIKE "%VALUE%" ? How?
In postgresql it works like this:
Tag.where("name iLIKE ANY ( array[?] )", words)
SQL RLIKE (REGEX)
Tag.where("name RLIKE ?", words.join("|"))
SQL select (not very efficient):
Tag.select{ |c| c.name =~ Regexp.new(words.join("|"), true) }
As a scope in Tag.rb (SQL)
scope :ilike_any, -> (words) { where("name RLIKE ?", words.join("|")) }
That enables you to do:
words = %w(word1 word2 word3)
Tag.ilike_any(words)
I have a table category which has two filed id (auto increment) and catname (string)
In some particular entry it has entered my user like
id | catname
1 | \\
2 | abcd
3 | \\
4 | >> asd
5 | \\
6 | \\
7 | \\
I want to delete this \\ entry but it is not found by select query
How do I delete this \\ entry ?
And I also use 'php' so any way to delete \\ entry by php or by phpmyadmin panel please help me.
You can use this query:
DELETE FROM `cat` WHERE `catname` = '\\\\';
Fiddle: http://www.sqlfiddle.com/#!2/ef33d/1
you can also check the values at the time of post by using "trim" or "str_replace"
trim will remove all of your whitespaces and and other characters at the beginning of the string
or you can use str_replace
The str_replace() function replace all occurrences of the search string with the replacement string
"mixed str_replace ( mixed $search , mixed $replace , mixed $subject <, int &$count > )"
This function works by the following rules:
If the string to be searched is an array, it returns an array
If the string to be searched is an array, find and replace is performed with every array element
If both find and replace are arrays, and replace has fewer elements than find, an empty string will be used as replace
If find is an array and replace is a string, the replace string will be used for every find value
Examples:
<?php
echo str_replace("world","Peter","Hello world!");
?>
output: Hello Peter!
<?php
$arr = array("blue","red","green","yellow");
print_r(str_replace("red","pink",$arr,$i));
echo "Replacements: $i";
?>
output: Array
(
<0> => blue
<1> => pink
<2> => green
<3> => yellow
)
Replacements: 1
or you can use regular expression "preg_replace" for that you have to learn regular-expresions for details on regular expression follow the link
http://www.php.net/manual/en/ref.pcre.php
1st way to delete from database is:
DELETE TABLE `TABLE_NAME` WHERE `CATNAME` = '\\';
This deletes all rows which have '\' entry.
DELETE TABLE `TABLE_NAME` WHERE `CATNAME` LIKE '\\';