I am building a query to give a row with multi variables in Laravel.
select * from Fruit where apple = red and banana = raw and orange = 1
how could I create a SQL query into Laravel in this condition?
$result = Fruit::where('apple ', red , 'banana ', raw , 'orange ', 1);
If you are using a recent version of Laravel, then you may define an associative array containing the conditions:
$conditions = ['apple' => 'red', 'banana' => 'raw', 'orange' => '1'];
$result = Fruit::where($conditions)->get();
This assumes that, as you have stated, you want to AND together some number of criteria only.
You can do it some ways
Solution 1:
$result = Fruit::whereApple('red')->whereBanana('raw')->whereOrange('1')->get();
Solution 2:
$result = Fruit::where('apple', 'red')->where('banana', 'raw')->where('orange', '1')->get();
Solution 3:
$result = Fruit::where([
'apple' => 'red',
'banana' => 'raw',
'orange' => '1'
])->get();
Solution 4:
$result = Fruit::where([
['apple', '=', 'red'],
['banana', '=', 'raw'],
['orange', '=', '1']
])
->get();
Related
LARAVEL 5.4 (but probably it's a more general SQL question)
Hello! I have a table with a structure:
Suppose it's my model 'Table'.
I want a query which:
uses (receives) variables :
$id of array ['id', 'string', integer]
where string is '<' or '>'
$status_not_bad = bool;
(if true - include all rows where 'status' !== 'bad' AND 'status' IS NULL);
for example, we are given:
$id = [['id', '>', 0]];
$status_not_bad = true;
Table::thisquery() ... ->get();
"get rows where status is not bad and id > 0" returns rows 1 and 3.
but if we given:
$id = [['id', '<', 3]];
$status_not_bad = true;
Table::thisquery() ... ->get();
"get rows where status is not bad and id < 3" returns row 1
(it should be same query which return those results using those variables).
Probably you end with something like this:
if ($status_not_bad) {
$nStatus = 'bad';
} else {
$nStatus = 'good';
}
Table::thisquery()->where('status', '<>', $nStatus)
->whereNotNull('status')
->where($id[0], $id[1], $id[2])
->get();
But it would be a good idea to check $id keys first.
Since row id = 3 you need <= in your where statement to have that row included in the result set
$id = ['id', '<=', 3];
So, I this works:
$chain = Sample::when($status_not_bad, function($query){
return $query->where('status', '<>', 'bad')
->orwhereNull('status');
})
->where([$id])
->get();
Iam trying to update 'sortOrder' column based on a given list of ids.
For example, if the given IDs are:
$orderList = ['id' =>'1','id' =>'5','id' =>'3']
ID of '1' => 'sortOrder column' = 1
ID of '5' => 'sortOrder column' = 2
ID of '3' => 'sortOrder column' = 3
Query statement:
$ids_array = array_pluck($orderList, 'id');
$ids_string = implode(',', $ids_array);
DB::statement(DB::raw('set #rownum=0'));
$result = DB::table('requirements')
->join('sections', 'sections.id', '=', 'requirements.section_id')
->whereIn('id', $ids_array)
->orderByRaw("FIELD(requirements.id, {$ids_string})")
->update([
'requirements.sortOrder' => DB::raw('#rownum := #rownum + 1'),
]);
But when I try to update using this query, I am getting an error:
SQLSTATE[HY000]: General error: 1221 Incorrect usage of UPDATE and ORDER BY
I need to select all products with specific attribute (barcolor) and then update attribute with another value.
EXAMPLE.
I would like to select all SKU with barcolor = LIGHT GREEN and update them to GREEN.
Thanks!
you can do this from backend. you can go to catalog > manage products > select all products > at the right side you can see update attributes option , select that and click on submit and you will redirect to another page and than give the value in required field and save it.
It can be achieve by programming also.
If you have attribute option ID than:
$sAttributeName = 'brands';
$mOptionValueId = 250; // 250 is Id of Brand 1
$newOptionValueId = 255; // 255 is Id of Brand 2
$productsCollection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect('*')
->addFieldToFilter(
$sAttributeName,
array(
'eq' => $mOptionValueId
)
);
$storeId = Mage::app()->getStore()->getStoreId();
foreach($productsCollection as $product) {
$productId = $product->getId();
Mage::getSingleton('catalog/product_action')->updateAttributes(
array($productId),
array('brands' => $newOptionValueId),
$storeId
);
}
If you do not have attribute option ID than you can use the option value directly as:
$sAttributeName = 'brands';
$mOptionValue = 'Brand 1';
$newOptionValue = 'Brand 2';
$productsCollection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect('*')
->addFieldToFilter(
$sAttributeName,
array(
'eq' => Mage::getResourceModel('catalog/product')
->getAttribute($sAttributeName)
->getSource()
->getOptionId($mOptionValue)
)
);
$storeId = Mage::app()->getStore()->getStoreId();
foreach($productsCollection as $product) {
$productId = $product->getId();
Mage::getSingleton('catalog/product_action')->updateAttributes(
array($productId),
array('brands' => Mage::getResourceModel('catalog/product')
->getAttribute($sAttributeName)
->getSource()
->getOptionId($newOptionValue)),
$storeId
);
}
If you have the list of the entity_ids for all the products and you are using a custom attribute, you can run an SQL query for each and every product like so:
UPDATE `catalog_product_entity_varchar` SET value = 'NEW BLACK' WHERE entity_id = '12345' AND attribute_id = 'attribute_id_here';
You can also filter the fields by:
SELECT entity_id,value FROM catalog_product_entity_varchar WHERE value LIKE 'something';
I'm trying to do something like:
$results = $query->leftJoin('checklist_items', function($join) use ($days) {
$join->on('users.id', '=', 'checklist_items.user_id')
->on('checklist_items.due_date', 'IN', $days);
})
->where('checklist_items.user_id', null)
->limit(10)
->get();
This is an example of the query I'm attempting to execute:
SELECT *
FROM users
LEFT JOIN checklist_items
ON users.id = checklist_items.user_id
AND checklist_items.due_date IN ('2015-07-09', '2015-07-10')
WHERE checklist_items.user_id IS NULL
ORDER BY users.id
So this is a left outer join. In query builder, most of this is no problem. The problem is the fact that my AND line uses an IN query. If it were part of a WHERE clause I would use ->whereIn but since I need it in the Join clause, whereIn won't work and there is no orIn or some such.
Suggestions?
You can use ->whereIn() within the ->leftJoin() closure (Tested in Laravel 5.7.16):
$days = ['2015-07-09', '2015-07-10'];
$results = \DB::table('users')
->leftJoin('checklist_items', function($join) use ($days) {
$join->on('users.id', '=', 'checklist_items.user_id')
->whereIn('checklist_items.due_date', $days);
})
->where('checklist_items.user_id', null)
->orderby('users.id')
->get();
Output from dd(\DB::getQueryLog(); produces your example query:
array:1 [▼
0 => array:3 [▼
"query" => "select * from `users` left join `checklist_items` on `users`.`id` = `checklist_items`.`user_id` and `checklist_items`.`due_date` in (?, ?) where `checklist_items`.`user_id` is null order by `users`.`id` asc ◀"
"bindings" => array:2 [▼
0 => "2015-07-09"
1 => "2015-07-10"
]
"time" => 6.97
]
]
I think you would need to use DB::raw() so it doesn't try to quote your days and wrap your days in parenthesis as well. This should do the trick.
$days = '(\'2015-07-09\', \'2015-07-10\')';
$results = DB::table('users')->leftJoin('checklist_items', function($join) use ($days) {
$join->on('users.id', '=', 'checklist_items.user_id')
->on('checklist_items.due_date', 'IN', DB::raw($days));
})
->where('checklist_items.user_id', null)
->limit(10)
->toSql();
echo $results;
This Query will Work
$results = DB::table('users')
->join('checklist_items','checklist_items.user_id','=','users.id')
->whereIn('checklist_items.due_date',['2015-07-09', '2015-07-10'])
->whereNull('checklist_items.user_id')
->orderBy('users.id','asc')
For Laravel 7 and above use whereIn instead of on :
$join->on('users.id', '=', 'checklist_items.user_id')
->whereIn('checklist_items.due_date',$days);
I want to generate a SQL query like the following using Ruby's Sequel:
SELECT * FROM Objects WHERE (color = "red" AND shape = "triangle") OR
(color = "blue" AND shape = "square") OR
(color = "green" AND shape = "circle")
I want to build this query programmatically from a list of conditions, so that I can do something like this:
conditions = [[[:color, "red"], [:shape, "triangle"]],
[[:color, "blue"], [:shape, "square"]],
[[:color, "green"], [:shape, "circle"]]]
DB[:Users].where(conditions.sql_or)
It doesn't have to follow that exact form, but I want to be able to build the conditions programmatically, so it's not sufficient to be able to construct this query by hand.
Try this:
conditions = [
{:color => "red", :shape => "triangle"},
{:color => "blue", :shape => "square"},
{:color => "green", :shape => "circle"}
]
head, *tail = *conditions
tail.inject(DB[:Users].filter(head)){|mem,obj| mem.or(obj) }
I get:
=> #<Sequel::Postgres::Dataset: "SELECT * FROM \"Users\" WHERE (((\"color\" = 'red') AND (\"shape\" = 'triangle')) OR ((\"color\" = 'blue') AND (\"shape\" = 'square')) OR ((\"color\" = 'green') AND (\"shape\" = 'circle')))">
I think this will return an equivalent result, using a different SQL query:
DB[:Objects].where('(color, shape) in ?', conditions.sql_value_list).sql
=> "SELECT * FROM `Objects` WHERE ((color, shape) in (('red', 'triangle'), ('blue', 'square'), ('green', 'circle')))"
sql_value_list is documented in http://sequel.rubyforge.org/rdoc/classes/Array.html
Otherwise use:
objects = DB[:Objects].where(conditions[0])
conditions[1 .. -1].each { |c| objects = objects.or(c) }
Which results in:
SELECT * FROM `Objects` WHERE (((`color` = 'red') AND (`shape` = 'triangle')) OR ((`color` = 'blue') AND (`shape` = 'square')) OR ((`color` = 'green') AND (`shape` = 'circle')))
I was looking at Iain's answer, and it's basically the same as my second one, only more succinct; I like its elegance.