QueryBuilder and inner join - sql

Here is the request :
select concat(user.nom, ' ', user.prenom), trace.action
from MyBundle:Ttrace trace
innerjoin MyBundle:User user on user.id = trace.user
where trace.datfin is null
Can somebody translate that using queryBuilder ?
Thank you
I tried this but it does not work :
$this->getEntityManager()->createQueryBuilder()
->select("trace.action")
->addSelect("concat(user.nom, ' ', user.prenom)")
->from('MyBundle:Ttrace', 'trace')
->innerjoin('trace', 'MyBundle:User', 'user', 'user.id = trace.user')
->where('trace.datfin is null');
But it does not work.
I also tried :
$this->getEntityManager()->createQueryBuilder()
->select("trace.action")
->addSelect("concat(user.nom, ' ', user.prenom)")
->from('MyBundle:Ttrace', 'trace')
->join('MyBundle:User', 'user')
->where('trace.datfin is null');
but sql query is wrong with:
innerjoin user on (trace.datfin is null) NONSENSE!! and of course no where in the sql query
So, does somebody know (it is easy they say) how to build it (with a query builder)
ty

Hoping it is gonna help somebody :
$qb = $this->getEntityManager()->createQueryBuilder()
->select('trace.action')
->addSelect("concat(user.nom, ' ', user.prenom)")
->from('MyBundle:Ttrace', 'trace');
$qb->join('MyBundle:User', 'u', Join::WITH, $qb->expr()->eq('trace.user', 'u.id'));
$qb->where($qb->expr()->isNull('trace.datfin');

Related

Problem to convert a SQL query to an Laravel Query Builder

I want to convert this SQL Query to LAravel SQL Builder but i don't know why I already read the laravel documentation but I can't find the answer
SQL Query:
SELECT
CONTRATO,
CASE WHEN RAZONSOCIAL IS NULL OR RAZONSOCIAL = ''
THEN ISNULL(PATERNO, '') + ' ' + ISNULL(MATERNO, '') + ' ' + ISNULL(NOMBRES, '')
ELSE RAZONSOCIAL
END AS NOMBRE,
CADENAUNICA,
CLAVERASTREO,
FECHAASIENTO,
IDGARANTIA,
RutaGuardadoPDF,
RutaGuardadoXML
FROM
DEUDORES AS D
LEFT JOIN
RELACIONES AS R
ON D.RUGID = R.RUGID
WHERE CONTRATO = 'A1412015'
AND D.AcreedorId IN (
SELECT
ACREEDORID
FROM
[MasterCLI].[dbo].[Rrug]
WHERE FIDEICOMISOID = 5
)
and i do this code in laravel
$AcreedorFide = \DB::connection('sqlsrv')
->table('Rrug')
->select('AcreedorID')
->where('Fideicomiso', $fideicomiso)
->get();
$BoletaRUG = \DB::connection('RUG')
->table('Deudores')
->select(
'Contrato',
'CadenaUnica',
'ClaveRastreo',
'FechaAsiento',
'IdGarantia',
'RutaGuardadoPDF',
'RutaGuardadoXML'
)
->select(DB::raw('CASE WHEN RAZONSOCIAL IS NULL'))
->leftJoin('Relaciones','Deudores.RugId', '=', 'Relaciones.RugId')
->where('Contrato', $Contrato)
->wherein('Acreedorid', $AcreedorFide)
->get();
The most SQL-like way of remaking this query in the Query Builder is the following:
DB::connection('sqlsrv')->query()
->select(
'CONTRATO',
'CADENAUNICA',
'CLAVERASTREO',
'FECHAASIENTO',
'IDGARANTIA',
'RutaGuardadoPDF',
'RutaGuardadoXML'
)
->selectRaw(
"CASE WHEN RAZONSOCIAL IS NULL OR RAZONSOCIAL = '' ".
"THEN ISNULL(PATERNO, '') + ' ' + ISNULL(MATERNO, '') + ' ' + ISNULL(NOMBRES, '') ".
"ELSE RAZONSOCIAL ".
"END AS NOMBRE"
)
->from('DEUDORES', 'D')
->leftJoin('RELACIONES AS R', 'D.RUGID', '=', 'R.RUGID')
->where('CONTRATO', '=', 'A1412015')
->whereIn('D.AcreedorId', function ($query) {
$query->select('ACREEDORID')
->from('MasterCLI.dbo.Rrug')
->where('FIDEICOMISOID', '=', 5);
})
->get();
For anyone stuck on translating queries, as the comments have stated, the easiest way to remake large, complex-looking queries in the builder is by dumping the query using ->toSql() instead of ->get() and checking if it's missing something or not. Trial and error.
My personal advice is to start from the subqueries and work your way up. Also, Some differences/shorthands:
Instead of DB::connection(...)->query()->select(...)->from('DEUDORES', 'D')->where(...),you can specify the main table you're querying first:DB::connection(...)->table('DEUDORES', 'D')->select(...)->where(...)
If the comparison operator is '=' you can leave it implied. In this example:
leftJoin('RELACIONES AS R', 'D.RUGID', '=', 'R.RUGID') becomes leftJoin('RELACIONES AS R', 'D.RUGID', 'R.RUGID')
where('CONTRATO', '=', 'A1412015') becomes where('CONTRATO', 'A1412015')
If you use the same connection as the default one (DB_CONNECTION in your .env file), you can skip the connection(...) in the queries. DB::connection(...)->table(...) becomes DB::table(...).

LINQ Query to search for users with partial name

I have this SQL query:
SELECT
*
FROM
employeeTable
WHERE
(
concat(first_name, ' ', last_name) like concat('%', replace(#MatchString, ' ', '%'), '%')
or
concat(last_name, ' ', first_name) like concat('%', replace(#MatchString, ' ', '%'), '%')
)
It works perfectly by searching both name and last name with partial values., by searching users with partial strings. So for example:
"ric jon" will find Rick Jones, Richard Jonesy, and Jonathan Prichter.
I have the following Linq Query, using Entity Framework:
from employee in context.Employee
where employee.first_name.Contains(matchString)
|| employee.last_name.Contains(matchString)
select employee
But the string "ric jon" does not find anything.
I can't seem to make that linq query work the same as the SQL query.
That SQL wouldn't in fact find those records you sampled with the given "ric jon". What you are asking for is a special filter which IMHO requires a function that is not natively supported by the backend (you didn't specify your backend but anyway at least I don't know a backend that would support this natively). Something like this would work (note that you are getting the Employee records to local, this is not done at backend level):
Func<Employee, string[], bool> match = (emp, _parts) => {
return
((emp.FirstName.IndexOf(_parts[0],StringComparison.CurrentCultureIgnoreCase ) != -1) &&
(_parts.Length == 1 || emp.LastName.IndexOf(_parts[1], StringComparison.CurrentCultureIgnoreCase) != -1)) ||
((_parts.Length == 1 || emp.FirstName.IndexOf(_parts[1], StringComparison.CurrentCultureIgnoreCase) != -1) &&
(emp.LastName.IndexOf(_parts[0], StringComparison.CurrentCultureIgnoreCase) != -1));
};
string search = "ric jon";
var result = context.Employee.AsEnumerable()
.Where(n => match(n, search.Split()));
Update:
You can use this one which would be supported by many backends:
string search = "ric jon";
string[] parts = search.ToLowerInvariant().Split();
string p1 = parts.Length < 1 ? "" :parts[0];
string p2 = parts.Length < 2 ? "" :parts[1];
var result = context.Employee.Where(n =>
((n.FirstName.ToLowerInvariant().Contains(p1) &&
n.LastName.ToLowerInvariant().Contains(p2))) ||
((n.FirstName.ToLowerInvariant().Contains(p2) &&
n.LastName.ToLowerInvariant().Contains(p1))));

Unable to left join on multiple tables with PhalconPHP's createBuilder?

Maybe I am doing something wrong here, but I am unable to join on multiple tables when using createBuilder(). Here is an example query.
$test = $this->modelsManager->createBuilder()
->from('TABLE1')
->leftJoin('TABLE2', 'TABLE1.id = TABLE2.table_one_id')
->leftJoin'TABLE3', 'TABLE3.id = TABLE2.table_three_id')
->where('TABLE1.id = :id:', array('id' => $id))
->groupBy(array('TABLE1.id'))
->getQuery()
->execute();
There error indicates that the SQL query is probably not being generated correctly by the framework, but I could very well be doing something wrong. It appears that no space is being added before the additional LEFT join.
Unknown column 'TABLE2.table_one_idLEFT' in 'on clause''
Any insight would be greatly appreciated.
You will need to add a space at the end of first join condition:
$test = $this->modelsManager->createBuilder()
->from('TABLE1')
->leftJoin('TABLE2', 'TABLE1.id = TABLE2.table_one_id ')
->leftJoin('TABLE3', 'TABLE3.id = TABLE2.table_three_id')
->where('TABLE1.id = :id:', array('id' => $id))
->groupBy(array('TABLE1.id'))
->getQuery()
->execute();

Joomla nBill user / client name query

I'm attempting to do a rather complex SQL query, it's getting way out of my league, I think I'm close on this, my forehead hurts now, I toss my hands up and ask for an assist.
<?php
$db =& JFactory::getDBO();
$userid = "SELECT * FROM #__users WHERE id='".$row->userid."' ";
$db->setQuery
("
select #__nbill_contact.user_id as userid, concat(#__nbill_entity.company_name, ' - ', #__nbill_contact.first_name, ' ',
#__nbill_contact.last_name) as contact_entity from #__nbill_entity
INNER JOIN #__nbill_entity_contact on #__nbill_entity.id = #__nbill_entity_contact.entity_id
INNER JOIN #__nbill_contact on #__nbill_entity_contact.contact_id = #__nbill_contact.id and #__nbill_contact.user_id > 0"
);
$user_type_detail = $db->loadAssoc();
ech $user_tpe_detail["contact_entity"]
;?>
Thanks in advance!

createQueryBuilder IN clause

I´m working with Symfony2 and I need to execute this SQL for example:
select detformacion.* from detformacion
left join formacion
on detformacion.formacion_id = formacion.id
left join detcurso
on formacion.id = detcurso.formacion_id
where detcurso.id IN ('143','144');
For that, I have this in my Repository:
public function getSeleccion() {
$em = $this->getEntityManager();
$query = $em->createQueryBuilder()
->select('d')
->from('GitekUdaBundle:Detformacion', 'd')
->leftJoin('d.formacion', 'f')
->leftJoin('f.detcursos', 'det')
->where('det.id = :miarray')
->setParameter('miarray',array('143','144'))
->getQuery()
;
return $query->getResult();
}
I tried with ->where('det.id IN :miarray') but I´m getting errors all the time.
Any help or clue?
thanks in advance.
UPDATE: The problem is setting the parameters.
Missing parentheses after the IN operator :
->where('det.id IN (:miarray)')
->setParameter('miarray', array('143','144'))