Lets say of I have this query SELECT * FROM table WHERE id IN (1,2,3,4);
In my current use case my ids are in an array like so [1,2,3,4]
How could I do the same query using the array data structure?
i.e. SELECT * FROM table WHERE id IN (myarray);
Edit: this is in ruby :)
Try this:
SELECT * FROM table WHERE id IN (myarray.map {|i| "\"#{i}\""}.join(", "));
You could convert the array to a comma separated string using the myarray.join(',') method.
The final code would look like this:
query = "SELECT * FROM table WHERE id IN (#{myarray.join(',')})"
You might run into some problems if the array values are strings, but it works just fine for integers.
User.where(id: [1, 2, 3, 4, nil]).to_sql
# SELECT "users".* FROM "users"
# WHERE ("users"."id" IN (1, 2, 3, 4) OR "users"."id" IS NULL)
or, if you can't/don't want to use where, you can drop into Arel to get just the IN string:
User.arel_table[:id].in([1,2,3,4]).to_sql
# => "users"."id" IN (1, 2, 3, 4)
though with this, you don't automatically get that nifty nil handling. If you don't have an ActiveRecord Model, but just using ActiveRecord::Base to execute queries in your database (as mentioned in the comments) you can do:
table = Arel::Table.new(:table) # :table is the name of the table in db
table[:id].in([1,2,3,4]).to_sql
# => "table"."id" IN (1, 2, 3, 4)
table.where(table[:id].in([1,2,3,4])).project(Arel.sql('*')).to_sql
# => SELECT * FROM "table" WHERE "table"."id" IN (1, 2, 3, 4)
And, avoiding Arel/ActiveRecord as much as possible, you can just do
ActiveRecord::Base.send(:sanitize_sql, ['id in (?)', [1,2,3,4]])
# => "id in (1,2,3,4)"
Related
This is the update code
$clients = OpClient::find(['id'])->where(['status'=>'Active'])->all();
foreach($clients as $client)
{
$array[] = $client['unit_id'];
$unit = OpUnit::find()->where(['id'=>$array]);
file_put_contents('test.txt',print_r($client['unit_id'],true));
$connection = Yii::$app->db;
$connection->createCommand()->update('op_unit', ['selected' => 'Yes'], 'id='.$array.'')->execute();
}
How should I type in the update query where the id is an array? It keep showing error Array to string conversion. Any advice will be apprecieated. Thanks
should be this way ..
$connection->createCommand()->update('user',
['selected' => 'Yes'],['id' => $array])->execute();
try the real sql code using
$myRawSql= $connection->createCommand()->update('user',
['selected' => 'Yes'],['id' => $array])>getRawSql();
var_dump($myRawSql);
For searching you can use the IN condition. i.e
->andWhere(['in', 'id', [1, 2, 3]])
// Query will be: WHERE id IN (1, 2, 3)
http://www.yiiframework.com/doc-2.0/guide-db-query-builder.html
in: operand 1 should be a column or DB expression. Operand 2 can be
either an array or a Query object. It will generate an IN condition.
If Operand 2 is an array, it will represent the range of the values
that the column or DB expression should be; If Operand 2 is a Query
object, a sub-query will be generated and used as the range of the
column or DB expression. For example, ['in', 'id', [1, 2, 3]] will
generate id IN (1, 2, 3). The method will properly quote the column
name and escape values in the range. The in operator also supports
composite columns. In this case, operand 1 should be an array of the
columns, while operand 2 should be an array of arrays or a Query
object representing the range of the columns.
So basically you need to pass your array to IN for search.
For update you can use same Where syntax in updateAll command i.e
// UPDATE customer SET status = 1 WHERE id IN (1, 2, 3)
http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#updating-multiple-rows
Customer::updateAll(['status' => Customer::STATUS_ACTIVE], ['in', 'id', [1, 2, 3]]);
Hope this helps. Thanks.
You can use updateAll query :
$update = OpUnit::updateAll(['selected' => 'Yes'],['id' => $array]);
It returns number of rows updated.
Refer : http://www.yiiframework.com/doc-2.0/yii-db-activerecord.html#updateAll()-detail
I have a JSON column named prices_and_tags in which there are values in JSON array:
[{'price' => 100, 'tag' => 'Watch'}, {'price' => 200, 'tag' => 'Book'}]
If I want to search prices_tags where tag = 'Watch' in any array index, it's not working.
Query is like this:
select * from products where prices_and_tags->"$[*].tag" = 'Watch'
this gives 0 results.
But this query works for first or second array index, like this:
select * from products where prices_and_tags->"$[0].tag" = 'Watch'
I referred to this: https://dev.mysql.com/doc/refman/5.7/en/json-path-syntax.html for query syntax.
Thanks.
Have you tried this
select * from products where prices_and_tags->"$.tag[*]" = 'Watch'
Ref: https://dev.mysql.com/doc/refman/5.7/en/json.html
I'm working now on some dictionary and i'm downloading source from multiple dictionaries into mysql database.
I have two tables:
Words
ID and Word
ie. VALUES:
123, "Hakunamatata"
332, "Boom"
Source
ID, WordID and Numerical ie. VALUES:
1, 123, 7676552
2, 332, 651365
Now, i would like to update data in Source this way:
find ID in Words WHERE Word = "example"
put datum (WordID, "Number") into Source
BUT
If there is no such Word in Words - create it.
I need to do about 100000 of queries of this type, but it does not need to be very fast ;)
I've tried to do something like this:
REPLACE INTOsjp-dict.Words
LEFT JOINsjp-dict.Source-Wiktionary
ONWords.ID =Source-Wiktionary.WordID
SET
Word= IF(WordIS NULL, "Apulia",Word),
WordID= IF(Source-Wiktionary.WordID IS NULL ANDWord= "Apulia",Words.ID,WordID),
WikiWordID= IF(Word= "Apulia", 123, WikiWordID)
But it does not work...
Done with two sql commands:
$sql = 'INSERT IGNORE INTO Words (Word) VALUES '. $sql_words;
$sql2 = 'INSERT IGNORE INTO "Source-Wiktionary" (WordID, WikiWordID) VALUES '. $sql_values;
Where WordID is definied by
SELECT ID FROM Words WHERE Word = "'. strtolower($cma[2]). '" LIMIT 1
I have a table like this
The table in mysql
and I have a variable x in matlab
x=[1 5 6 8 10 21 99];
now I want to select like this
select * from tablename where key1 = x
I know mysql query must be string, and my variable x in matlab may be too long.
So how to do this in matlab? I failed in searching. Thanks
conn = database('instancename','username','password');
I know I can do this like
sql = 'select * from tablename where key in (1,5,6,8,10,21,99)'
The question is my x isn't constant and sometime could be a 1*N cell ( whose element is char), I want to put it into a script.
In SQL Server you write your query like this:
select * from tablename where key1 in {1, 5, 6, 8, 10, 21, 99}
I don't know about MY SQL but I imagine it is very similar. Which means all you need to do is convert x to the string '1, 5, 6, 8, 10, 21, 99' which you could do like this:
x_str = strjoin(cellstr(num2str(x'))',',')
and now the whole query becomes
query = sprintf('SELECT * FROM tablename WHERE key1 IN {%s}', x_str);
As an aside, another way to create x_str could be:
x_str = sprinft('%d, ', x);
x_str(end) = [];
I have a django model:
class Field:
choice = models.CharField(choices=choices)
value = models.CharField(max_length=255)
In my database I have some cases where there are 3 "fields" with the same choice, and some cases where there is 1 field of that choice
How can I order the queryset so it returns, sorted by choice, but with all ones in a set of 3 at the start?
For example
[1,1,1,3,3,3,4,4,4,2,5] where 1,2,3,4,5 are possible choices?
This is the best I can do using django's ORM. Basically, just like in SQL, you have to construct a custom order_by statement. In our case, we'll place it in the SELECT and then order by it:
1) Get a list of choices sorted by frequency: [1, 3, 4, 2, 5]
freq_list = (
Field.objects.values_list('choice', flat=True)
.annotate(c=Count('id')).order_by('-c', 'choice')
)
2) Add indexes with enumerate: [(0,1), (1,3), (2,4), (3,2), (4,5)]
enum_list = list(enumerate(freq_list))
3) Create a list of cases: ['CASE', 'WHEN choice=1 THEN 0', ..., 'END']
case_list = ['CASE']
case_list += ["WHEN choice={1} THEN {0}".format(*tup) for tup in enum_list]
case_list += ['END']
4) Combine the case list into one string: 'CASE WHEN choice=1 THEN 0 ...'
case_statement = ' '.join(case_list)
5) Finally, use the case statement to select an extra field 'o' which will be corresponding order, then just order by this field
Field.objects.extra(select={'o': case_statement}).order_by('o')
To simplify all this, you can put the above code into a Model Manager:
class FieldManager(models.Manager):
def get_query_set(self):
freq_list = (
Field.objects.values_list('choice', flat=True)
.annotate(c=Count('id')).order_by('-c', 'choice')
)
enum_list = list(enumerate(freq_list))
case_list = ['CASE']
case_list += ["WHEN choice={1} THEN {0}".format(*tup) for tup in enum_list]
case_list += ['END']
case_statement = ' '.join(case_list)
ordered = Field.objects.extra(select={'o': case_statement}).order_by('o')
return ordered
class Field(models.Model):
...
freq_sorted = FieldManager()
Now you can query:
Field.freq_sorted.all()
Which will get you a Field QuerySet sorted by frequency of choices
You should make a function and detect which is repeated to select unique, then calling from mysql as a function over mysql