Laravel: Sort a column ASC but 0 come last - sql

Using Laravel, to order by a column ascending, but 0 to come last. This is how we do in normal SQL:
SELECT * FROM your_table ORDER BY your_field = 0, your_field;
I want to know how to do in Laravel.
Many thanks

Use orderByRaw()
Assuming Your_Table model
Your_Table::orderByRaw('your_field = 0, your_field')->get();

You can try orderByRaw function.
for example :
$data = new YourModel();
$data = $data->orderByRaw('your_field = 0', 'ASC', 'your_field')->get();

I think we can use DB::raw, so the usage maybe.
DB::select( DB::raw( "SELECT * FROM your_table ORDER BY your_field = 0, your_field" ) );

return $this->your_model
->orderByRaw('display_order = 0, display_order ASC')
->get();

Related

How count by the first letters in Laravel Query Builder?

I want to make a count by the first letters... I have this column
I would like to count each OE rows and each GICS rows
I'm working with this query
$data4 = DB::table('incidencias')
->select(DB::raw('grupo_asig as grupo_asig'), DB::raw('count(*) as number'))
->whereNotIn('grupo_asig', [''])
->groupBy('grupo_asig')
->orderBy('number', 'desc')
->get();
Use CASE WHEN and count the field like OE and ASIG
$data4 = DB::table('incidencias')
->select(DB::raw("(CASE WHEN grupo_asig LIKE 'OE%' THEN 'OE'
WHEN grupo_asig LIKE 'GICS%' THEN 'GICS'
END) AS grupo_asig_type"),
DB::raw('COUNT(*) as number'))
->whereNotIn('grupo_asig', [''])
->groupBy('grupo_asig_type')
->orderBy('number', 'desc')
->get();
You should try to use the [LIKE][1] function then and add it to your query:
->where('grupo_asig', 'like', 'OE%')
->where('grupo_asig', 'like', 'GICS%')
Edit:
I tried a lot around and came to this solution and made a SQL fiddle: http://sqlfiddle.com/#!9/06a39b/8
Does it help you?
You could use Collections. No real need to change your query much.
$data4 = DB::table('incidencias')
->select('grupo_asig')
->selectRaw('count(*) as number'))
->whereNotIn('grupo_asig', [''])
->groupBy('grupo_asig')
// ->orderBy('number', 'desc') Unless you use this array somewhere, it's not needed.
->get();
use Illuminate\Support\Str;
...
// php >= 7.4.0
$oe_count = $data4->filter(fn($data) => Str::startsWith($data->grupo, 'OE '))->count();
$gigs_count = $data4->filter(fn($data) => Str::startsWith($data->grupo, 'GIGS '))->count();
// php < 7.4.0
$oe_count = $data4->filter(function ($data) {
return Str::startsWith($data->grupo, 'OE ');
})->count();
$gigs_count = $data4->filter(function ($data) {
return Str::startsWith($data->grupo, 'GIGS ');
})->count();
Starting with Laravel 6, you can also use cursor() instead of get() in your query to return a LazyCollection. It's faster for this scenario.
I would suggest using a query for that:
refer to this answer
SELECT
LEFT(grupo_asig, 1) AS first_letter,
COUNT(*) AS total
FROM incidencias
GROUP BY first_letter

Zend-Db 2.9 - SQL with RAND order

guys, I need help, I am using zend-db 2.9 - and I have an sql that need the rand() order, but the result of this query came wrong
my code:
$sql = new Sql($this->dbAdapter);
$select = $sql->select(
['a'=>$this->table]
);
$select->order("RAND() ASC");
$select->limit(1);
$stt = $sql->prepareStatementForSqlObject($select);
$res = $stt->execute();
result is :
SELECT `a`.* FROM `mytable` AS `a` ORDER BY `RAND``(``)` ASC LIMIT 1
how to fix it?
I found the answer fot this: Just Add new Expression("RAND()")
$sql = new Sql($this->dbAdapter);
$select = $sql->select(
['a'=>$this->table]
);
$select->order([new Expression("RAND() ASC")]);
$select->limit(1);
$stt = $sql->prepareStatementForSqlObject($select);
$res = $stt->execute();

How to get a single value in findbyPk() method in yii?

In my controller
$agent = University::model()->findByPK($university_id);
I hope it will return value of a row of value.
I want a single attribute(field3) value say university_name, (with out using findByPK), how to get it
SELECT field3 FROM table [WHERE Clause]
Try this
$usercriteria = new CDbCriteria();
$usercriteria->select = "university_name";
$usercriteria->condition = "university_id=$university_id";
$university = University::model()->findAll($usercriteria);
echo $university->university_name;
Or simply do like u did first
$agent = University::model()->findByPK($university_id);
echo $agent-> university_name;
$agent = University::model()->findByPK($university_id);
echo $agent->university_name;
It should be like this:
$agent = University::model()->findByPK($university_id)->university_name;
Try this:
$university_name = University::model()->findByPK($university_id, array('select'=>'univeersity_name'))->university_name;
#Query: SElECT university_name FROM table_name where id=x;
Instead of
$university_name = University::model()->findByPK($university_id)->university_name;
#Query: SElECT * FROM table_name where id=x;
Second query returns all the fields. So better to avoid those fields are not necessary.
in case if you need to view on the yii _views, i have implemented this on my project
i put this inside my '_view.php' at /protected/views/myTable/
$agent = University::model()->findByPK($data->id_university/*this is the PK field name*/);
echo $agent->university_name /*university field name*/;
sorry again for my bad english :o
It can be done like this:
$agent = University::model()->findAllByAttributes(array('field3'),"WHERE `id` = :id", array(':id' => $university_id));
First argument of findByAttributes is an array of attributes you wish it to return. If left empty it returns all (*).

How can I rewrite this SQL into CodeIgniter's Active Records?

SELECT *, SUM(tbl.relevance) AS relevance FROM
(
(
SELECT q_id,
MATCH(a_content) AGAINST ('бутон') AS relevance
FROM answers
WHERE
MATCH(a_content) AGAINST ('бутон')
)
UNION
(
SELECT q_id,
(MATCH(q_content) AGAINST ('бутон')) * 1.5 AS relevance
FROM questions
WHERE
MATCH(q_content) AGAINST ('бутон')
)
) AS tbl
JOIN questions ON questions.q_id = tbl.q_id
GROUP BY tbl.q_id
ORDER BY relevance DESC
Codeigniter currently does not have support for subqueries in its Active Records class.
You'll simply have to use this:
$this->db->query($your_query, FALSE);
Remember to pass that second argument, so that Codeigniter doesn't try to escape your query.
Well there is indeed a simple hack for subqueries in codeigniter. You have to do the following
Go to system/database/DB_active_rec.php
There if you are using version 2.0 or greater change this
public function _compile_select($select_override = FALSE)
public function _reset_select()
Remove public keyword and you will be able to use subqueries
And now
$data = array(
"q_id",
"MATCH(a_content) AGAINST ('?????') AS relevance"
);
$this->db->select($data);
$this->db->from("answers");
$this->db->where("MATCH(a_content) AGAINST ('?????')");
$subQuery1 = $this->db->_compile_select();
// Reset active record
$this->db->_reset_select();
unset($data);
$data = array(
"q_id",
"(MATCH(q_content) AGAINST ('?????')) * 1.5 AS relevance"
);
$this->db->select($data);
$this->db->from("questions");
$this->db->where("MATCH(q_content) AGAINST ('?????')");
$subQuery2 = $this->db->_compile_select();
// Reset active record
$this->db->_reset_select();
unset($data);
$data = array(
"q_id",
"SUM(tbl.relevance) AS relevance"
);
$this->db->select($data);
$this->db->from("$subQuery1 UNION $subQuery2");
$this->db->join("questions","questions.q_id = tbl.q_id");
$this->db->group_by("tbl.q_id");
$this->db->order_by("relevance","desc");
$query = $this->db->get();

Zend Framework Db Select Join table help

I have this query:
SELECT g.title, g.asin, g.platform_id, r.rank
FROM games g
INNER JOIN ranks r ON ( g.id = r.game_id )
ORDER BY r.rank DESC
LIMIT 5`
Now, this is my JOIN using Zend_Db_Select but it gives me array error
$query = $this->select();
$query->from(array('g' => 'games'), array());
$query->join(array('r' => 'ranks'), 'g.id = r.game_id', array('g.title', 'g.asin', 'g.platform_id', 'r.rank'));
$query->order('r.rank DESC');
$query->limit($top);
$resultRows = $this->fetchAll($query);
return $resultRows;
Anyone know what I could be doing wrong? I want to get all the columns in 'games' to show and the 'rank' column in the ranks table.
I am going to assume you've solved this, but it would be nice to leave the answer for others.
Add this below the instantiation of the select object.
$query->setIntegrityCheck(false);
You could also type fewer characters....
$query = $this->select()
->from(array('g' => 'games'), array('title', 'asin', 'platform_id'))
->join(array('r' => 'ranks'), 'g.id = r.game_id', array('rank'))
->order('r.rank DESC')
->limit($top);
return $this->fetchAll($query);
Good luck!
Here's how I'd write it:
$query = $this->select();
$query->from(array('g' => 'games'), array('title', 'asin', 'platform_id'));
$query->join(array('r' => 'ranks'), 'g.id = r.game_id', array('rank'));
$query->order('r.rank DESC');
$query->limit($top);
$resultRows = $this->fetchAll($query);
return $resultRows;
Other example:
select n.content, n.date, u.mail
from notes n, users u
where n.id_us=u.id and reminder=current_date
$query = $this->select()
->from(array('n'=>'notes'),
array('content', 'date'))
->join(array('u'=>'users'), 'n.id_us=u.id and n.reminder=current_date',
array('mail'))
->setIntegrityCheck(false);
return $this->fetchAll($query);
That's work fine :)