How count by the first letters in Laravel Query Builder? - sql

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

Related

Laravel eloquent where with relationship

I am stuck on transforming this SQL query to an eloquent query in Laravel. The SQL query works (tested in Sequel) but I cannot write it in eloquent ...
SELECT faqs.question FROM faqs
JOIN categories c ON c.id = faqs.category_id
WHERE c.subsite = 'sport'
This is what I have tried so far, but it returns all the questions, (ignoring the subsite filter).
$cat = Faq::with(['category' => function($query) use ($subsite) {
$query->where('subsite', $subsite);
}])->get();
Thanks for the help
Try this
$cat = Faq::query();
if (isset($subsite) && !empty($subsite) {
$query->whereHas('category', function ($query) use ($subsite) {
$query->where('subsite', $subsite);
});
}
$query->with('category')->get();
as per you core sql query, here is your laravel query.
$data = DB::table('faqs')
->join('categories', 'categories.id', '=', 'faqs.category_id')
->select('faqs.question')
->where('categories.subsite', '=', 'sport')
->get();
Hope this will help you!

laravel query builder or inside where

I have the following query and i want to know if this is possible in laravel's querybuilder:
SELECT * FROM table WHERE (column = value OR column = value2) AND column2 LIKE '%value3%'
Your query should look like this:
DB::table('table')
->where(function($q) use ($value, $value2) {
$q->where('column', $value)
->orWhere('column', $value2);
})
->where('column2', 'like', '%'.%value3.'%')
->get();
If you have multiple values, you can put them into a simple array and use whereIn():
DB::table('table')
->whereIn('column', $valuesArray)
->where('column2', 'like', '%'.%value3.'%')
->get();
you can use closure in where for ex.
\DB::table('table_name')
->where(function($q){
$q->where('column', 'value1')
->orWhere('column', 'value2');
})
->where('column2', 'LIKE', '%value3%');
check here https://laravel.com/docs/5.3/queries#parameter-grouping
You can do this according to make desired query
DB::table('table_name')
->where('column', 'value1')
->orWhere('column', 'value2')
->where('column2', 'like', '%value3%');

Select sql code in Laravel

Following query returning six values
SELECT tbl_start FROM timetable inner join route ON tbl_rte_id = id WHERE rte_origin = "UL" and rte_destination = "HW" ORDER BY(tbl_start) DESC;
And my laravel code is returning only one value
$tables = Timetable::join('route', 'tbl_rte_id', '=', 'id')
->where('rte_origin', $origin, 'AND')
->where('rte_destination', $destination)
->orderBy('tbl_start', 'desc')
->get();
foreach ($tables as $table) {
$result[$table->id] = $table->tbl_start;
}
This laravel code is not similar or similar. Can anyone help me.
Change this part:
->where('rte_origin', $origin, 'AND')
// to:
->where('rte_origin', $origin)
It will know by default that it's AND operator
And if you want to provide this operator, then do this:
->where('rte_origin', '=', $origin, 'AND')
You may try something like this:
$tables = Timetable::join('route', 'tbl_rte_id', '=', 'timetable.id')
->where('rte_origin', $origin)
->where('rte_destination', $destination)
->orderBy('tbl_start', 'desc')
->get()->lists('tbl_start', 'id');
The $tables will contain an array of id => tbl_start pairs.
Add a listener in your routes.php
Event::listen('illuminate.query', function($sql){
var_dump($sql);
});
Then execute both queries and check if you have the same result

codeigniter change complex query into active record

I have a codeigniter app.
My active record syntax works perfectly and is:
function get_as_09($q){
$this->db->select('m3');
$this->db->where('ProductCode', $q);
$query = $this->db->get('ProductList');
if($query->num_rows > 0){
foreach ($query->result_array() as $row){
$row_set[] = htmlentities(stripslashes($row['m3'])); //build an array
}
return $row_set;
}
}
This is effectively
select 'm3' from 'ProductList' where ProductCode='$1'
What I need to do is convert the below query into an active record type query and return it to the controller as per above active record syntax:
select length from
(SELECT
[Length]
,CONCAT(([width]*1000),([thickness]*1000),REPLACE([ProductCode],concat(([width]*1000),([thickness]*1000),REPLACE((convert(varchar,convert(decimal(8,1),length))),'.','')),'')) as options
FROM [dbo].[dbo].[ProductList]) as p
where options='25100cr' order by length
I picture something like below but this does not work.
$this->db->select(length);
$this->db->from(SELECT [Length],CONCAT(([width]*1000),([thickness]*1000),REPLACE[ProductCode],concat(([width]*1000),([thickness]*1000),REPLACE((convert(varchar,convert(decimal(8,1),length))),'.','')),'')) as options
FROM [dbo].[dbo].[ProductList]);
$this->db->where(options, $q);
$this->db->order(length, desc);
Help appreciated as always. Thanks again.
You can use sub query way of codeigniter to do this for this purpose you will have to hack codeigniter. like this
Go to system/database/DB_active_rec.php Remove public or protected keyword from these functions
public function _compile_select($select_override = FALSE)
public function _reset_select()
Now subquery writing in available And now here is your query with active record
$select = array(
'Length'
'CONCAT(([width]*1000)',
'thickness * 1000',
'REPLACE(ProductCode, concat((width*1000),(thickness*1000),REPLACE((convert(varchar,convert(decimal(8,1),length))),'.','')),'')) as options'
);
$this->db->select($select);
$this->db->from('ProductList');
$Subquery = $this->db->_compile_select();
$this->db->_reset_select();
$this->db->select('length');
$this->db->from("($Subquery)");
$this->db->where('options','25100cr');
$this->db->order_by('length');
And the thing is done. Cheers!!!
Note : While using sub queries you must use
$this->db->from('myTable')
instead of
$this->db->get('myTable')
which runs the query.
Source

Extbase - get created sql from query

i want to get some database tables from my typo3 extensions.
The Extension is based on extbase.
The query always returns nothing but the data exists
I've tried this:
$query = $this->createQuery();
$query->statement('SELECT * FROM `my_table`
WHERE field = ? ORDER BY date DESC LIMIT 1',
array($condition));
$results = $query->execute();
and this:
$query = $this->createQuery();
$query->matching($query->equals('field', $condition));
$query->setOrderings(array('date' => Tx_Extbase_Persistence_QueryInterface::ORDER_DESCENDING));
$query->setLimit(1);
$results = $query->execute();
both returns null as result.
Is it possible to get the sql that the class creates to look where the bug is?
I've looked in some extbase persistent classes but didn't find a clue
EDIT:
For those who are interested.. i found a "solution".
If you create the query with the statement() method, you can print the query with this function
echo $query->getStatement()->getStatement();
It doesn't replace the placeholder.
But you can get the Variables with this method
var_dump($query->getStatement()->getBoundVariables());
Thats the best Solution that i found, without editing the extbase extenstions
In TYPO3 6.2 you can use Extbase DebuggerUtility to debug the query.
Add this code before $query->execute():
$queryParser = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Storage\\Typo3DbQueryParser');
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($queryParser->parseQuery($query));
For TYPO3 8.7+ use this code instead:
$queryParser = \TYPO3\CMS\Core\Utility\GeneralUtilityGeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser::class);
$doctrineQueryBuilder = $queryParser->convertQueryToDoctrineQueryBuilder($query);
$doctrineQueryBuilderSQL = $doctrineQueryBuilder->getSQL();
$doctrineQueryBuilderParameters = $doctrineQueryBuilder->getParameters();
Check this snippet, although it's not very comfortable in use it helps a lot:
in general you need this code at the end of the buildQuery(array $sql) method (*) - right before return $statement;
if (in_array("your_table_name", $sql['tables'])) {
var_dump($statement);
print_r($statement);
}
(*) Class file:
TYPO3 ver.: 4.x: typo3/sysext/extbase/Classes/Persistence/Storage/Typo3DbBackend.php
TYPO3 ver.: 6.x: typo3/sysext/extbase/Classes/Persistence/Generic/Storage/Typo3DbBackend.php
In 6.2.x ...
You can try within \TYPO3\CMS\Core\Database\DatabaseConnection::exec_SELECTquery method, just add the condition after fetching the $query, like (trim is important!):
public function exec_SELECTquery($select_fields, $from_table, $where_clause, $groupBy = '', $orderBy = '', $limit = '') {
$query = $this->SELECTquery($select_fields, $from_table, $where_clause, $groupBy, $orderBy, $limit);
if (trim($from_table) == 'fe_users') {
DebuggerUtility::var_dump($query);
}
// rest of method
An easy way without changing any Typo3 core code and not mentioned in any forum so far is using the php "serialize()" method:
$result = $query->execute();
echo (serialize($result));
In the result object you find the SQL query ("statement;" ...)
Improvement to biesiors answer:
As Extbase replaces some placeholders after calling buildQuery(), you might prefer to place the debug output into getObjectDataByQuery(), just after $this->replacePlaceholders($sql, $parameters, $tableName);
if (strpos($sql, "your_table_name.")) {
debug($sql, 'my debug output');
};
Also, better use debug() instead of var_dump().
[File: typo3\sysext\extbase\Classes\Persistence\Generic\Storage\Typo3DbBackend.php. Line 339 in version 6.1]:
$query = $this->createQuery();
$query->getQuerySettings()->setReturnRawQueryResult(TRUE);
$getHotelInfo = 'SELECT * FROM `my_table` WHERE field = ? ORDER BY date DESC LIMIT 1';
return $query->statement($getHotelInfo)->execute();
For executing query you have to write 'setReturnQueryResult' on your repository
I just extended the above snippet, with a $_GET condition.
for debugging, just append "?dbg_table=tx_some_of_my_tables" to your address, and you're ready to go ;-)
if (in_array($_GET['dbg_table'], $sql['tables'])) {
echo('<div style="background: #ebebeb; border: 1px solid #999; margin-bottom: 20px; padding: 10px;"><pre style="white-space: normal">'.$statement.'</pre></div>');
}
A cleaner way to debug your statements when using TYPO3 6.1 is to use the query parser of Typo3DbBackend.
$parser = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Storage\\Typo3DbBackend');
$params = array();
$queryParts = $parser->parseQuery($query, $params);
\TYPO3\CMS\Core\Utility\GeneralUtility::devLog('query', 'my_extension', 1, array('query' => $queryParts, 'params' => $params));
The parser returns an array containing the different parts of the generated SQL statement.
With TYPO3 6.2 the parseQuery method was moved to Typo3DbQueryParser and lost its second parameter.
i suggest set this in typo3conf/LocalConfiguration.php file under 'SYS' array
'SYS' => array(
......
'displayErrors' => 1,
'sqlDebug' => 1
.......
)
and then write wrong field name in query intentionally and then execute code.
this will show last query execute with error.