Converting MySQL query to Laravel - mysql

How I can convert this MySQL query to a Laravel query?
select *
from marques
where id in (select marque_id from products
where category_id = 'valeur1' or category_id in (select id from categories
where parent_id = 'Valeur1'))

I think your current query is equivalent to the following:
SELECT *
FROM marques m
LEFT JOIN products p
ON m.id = p.marque_id
LEFT JOIN categories c
ON p.category_id = c.id AND c.parent_id = 'Valeur1'
WHERE
p.category_id = 'valeur1' OR
c.id IS NOT NULL
Here is a rough guess at what your Laravel code might look like:
$res = DB::table('marques')
->join('products', 'marques.id', '=', 'products.marque_id')
->join("categories", function($join) {
$join->on('products.category_id', '=', 'categories.id')
->on('categories.parent_id', '=', 'Valeur1')
})
->whereNotNull('categories.id')
->orWhere('products.category_id', '=', 'valeur1')
->select('*')
->get();

Related

Laravel Join on Null

As the title says, how do I join on a null condition in Laravel? Take the following query:
SELECT * FROM TABLE1 a
INNER JOIN TABLE2 b
ON a.col1 = b.col1
OR a.col2 IS NULL
I've tried this but not the result I wanted:
$query = Table1::join('table2', function($join){
$join->on('table1.col1', '=', 'table2.col1');
$join->on('table1.col2', ????????);
});
Thanks.
you can use where inside JoinClause class, see advanced join clause:
$query = Table1::join('table2', function($join){
$join->on('table1.col1', '=', 'table2.col1')
->orWhereNull('table1.col2');
});

Convert mysql sub query to Laravel

How I can convert mysql query to laravel query? this is the query
SELECT
users.first_name,
users.id AS uid,
(
SELECT
COUNT(vpl_submissions.accept)
FROM
vpl_submissions
INNER JOIN vpl ON vpl_submissions.vpl = vpl.id
WHERE vpl.courseid = 2
AND vpl_submissions.accept = 1
AND vpl_submissions.userid = uid
) AS completed
FROM
users
INNER JOIN course_enroles ON users.id = course_enroles.user_id
WHERE course_enroles.course_id = 2
You can try this.
DB::table('users')
->join('course_enroles', 'users.id', '=', 'course_enroles.user_id')
->where("course_enroles.course_id", "=", 2)
->select(users.first_name,users.id AS uid,
DB::raw("(SELECT COUNT(vpl_submissions.accept) FROM
vpl_submissions INNER JOIN vpl ON vpl_submissions.vpl = vpl.id
WHERE vpl.courseid = 2
AND vpl_submissions.accept = 1
AND vpl_submissions.userid = uid) as completed")
)
->get();
This will help you.
Until you find a better solution, you can run raw queries like this
$result = DB::select(DB::raw("
select users.first_name,users.id AS uid,
(
select count(vpl_submissions.accept)
FROM vpl_submissions
INNER JOIN vpl on vpl_submissions.vpl = vpl.id
WHERE vpl.courseid=2 AND vpl_submissions.accept =1
AND vpl_submissions.userid = uid
) as completed
from users
inner join course_enroles on users.id = course_enroles.user_id
where course_enroles.course_id = 2
"));

Select statement into another select To Eloquant

How can I translate a SQL query like this to Eloquent or QueryBuilder :
SELECT * FROM studies
where studies.id in(SELECT study_id FROM (
SELECT max(studies.end_date), studies.id as study_id
from workers inner join resumes on workers.id=resumes.worker_id
inner join studies on resumes.id=studies.resume_id where
resumes.title="main" group by workers.id) as SQ2
Or globally
How can we make select from other select statement with eloquant for exemple:
SELECT a.id from (SELECT * FROM A INNER JOIN B ON a.id=b.id where a.id > 10) as SUBQ1
I think your current query doesn't get study_id with max end_date in all cases, you can try this one:
SELECT * FROM studies
where studies.end_date in (
SELECT max(studies.end_date)
from workers inner join resumes on workers.id=resumes.worker_id
inner join studies on resumes.id=studies.resume_id where
resumes.title="main" group by workers.id)
and if you want implement that with laravel Eloquant you can do it like this:
$result = DB::table('studies')
->select("*")
->whereIn('end_date', function($query){
$query->selectRaw("max(studies.end_date) as max_date")
->from('workers')
->join('resumes', 'workers.id', '=', 'resumes.worker_id')
->join('studies', 'resumes.id', '=', 'studies.resume_id')
->where('resumes.title', '=', 'main')
->groupBy('workers.id');
})
->get();
foreach($result as $row) {
print_r($row);
}

How to write this (left join, subquery ) in Laravel 5.1?

How to write this query in Laravel 5.1:
SELECT p.id, p.title, p.created_at, p.updated_at, u.name, COALESCE(c.comments_count, 0) AS comments_count, COALESCE(pl.status_sum, 0) AS status_sum
FROM posts p
LEFT OUTER JOIN users u ON u.id = p.user_id
LEFT OUTER JOIN (
SELECT pl.post_id, SUM(pl.status) AS status_sum
FROM postslikes pl
GROUP BY pl.post_id
) pl ON pl.post_id = p.id
LEFT OUTER JOIN (
SELECT c.post_id, COUNT(*) as comments_count
FROM comments c
GROUP BY c.post_id
) c ON c.post_id = p.id ORDER BY comments_count DESC
I need it for Pagination. I can perform this query raw without any problems but the manually paginator gives always the same results:
http://laravel.com/docs/5.1/pagination#manually-creating-a-paginator
The same problem as here: http://laravel.io/forum/07-22-2015-laravel-51-manual-pagination-not-working-as-expected
My attempt without success:
DB::table( 'posts' )
->select( 'posts.id', 'posts.title', 'posts.created_at', 'posts.updated_at', 'users.name', DB::raw( 'COALESCE( comments.body, 0 ), COALESCE( postslikes.status, 0 )' ) )
->leftJoin( 'users', 'users.id', '=', 'posts.user_id' )
->leftJoin( DB::raw( 'SELECT postslikes.post_id, SUM( postslikes.status ) FROM postslikes GROUP BY postslikes.post_id' ), function( $join )
{
$join->on( 'postslikes.post_id', '=', 'post.id' );
})
->leftJoin( DB::raw( 'SELECT comments.post_id, COUNT(*) FROM comments GROUP BY comments.post_id' ), function( $join )
{
$join->on( 'comments.post_id', '=', 'post.id' );
})
->get();
I think the problem is comments_count and status_sum?
Thanks!
To use subqueries with Laravel's query builder, you should add it to the join as follows:
->leftJoin(DB::raw("(SELECT [...]) AS p"), 'p.post_id', '=', 'posts.id')
It's also better to create an alias for calculated fields, as you did in your raw query:
COUNT(*) AS count
Despite this changes, unless I'm wrong, you can start by making your query simpler. Drop the subqueries, this way:
SELECT
p.id,
p.title,
p.created_at,
p.updated_at,
u.name,
COUNT(c.id) AS comments_count,
COALESCE(SUM(pl.status), 0) AS status_sum
FROM
posts p
LEFT OUTER JOIN
users u
ON
u.id = p.user_id
LEFT OUTER JOIN
postslikes pl
ON
pl.post_id = p.id
LEFT OUTER JOIN
comments c
ON
c.post_id = p.id
ORDER BY
comments_count DESC
GROUP BY
p.id
Then, with this new query, you can use Laravel to build it:
DB::table('posts')
->select([
'posts.id',
'posts.title',
'posts.created_at',
'posts.updated_at',
'users.name',
DB::raw('COUNT(comments.id) AS comments_count'),
DB::raw('COALESCE(SUM(postslikes.status), 0) AS status_sum'),
])
->leftJoin('users', 'users.id', '=', 'posts.user_id')
->leftJoin('comments', 'comments.post_id', '=', 'posts.id')
->leftJoin('postslikes', 'postslikes.post_id', '=', 'posts.id')
->orderBy('comments_count', 'DESC')
->groupBy('posts.id')
->get();
Note that I'm assuming you have a column named id in your comments table that is the primary key.

How to translate Fluent to Eloquent in Laravel

so i wanna try to get a filtering tag method, but in the database part is where i get lost, well kind of, because i wrote a raw query that works, but i need the Eloquent result so i can play with the relationships from the model class.
So here is the raw query:
$peticion = DB::select(DB::Raw("SELECT P.id, P.titulo, P.deadline, P.created_at, P.respuesta_id, U.usuario, C.titulo as categoria, C.clase_css as css, TG.Etiqueta
FROM peticiones P
JOIN usuarios U ON U.id = P.usuario_id
JOIN categorias C ON C.id = P.categoria_id
LEFT JOIN (
SELECT PT.peticion_id, T.nombre as Etiqueta
FROM tags T
JOIN peticion_tag PT ON PT.tag_id = T.id
) AS TG ON TG.peticion_id = P.id
JOIN (
SELECT PP.peticion_id
FROM (
SELECT PT.peticion_id, count(PT.peticion_id) AS conteo
FROM peticion_tag PT
WHERE PT.tag_id IN ( $etiquetas )
GROUP BY PT.peticion_id
) PP
WHERE PP.conteo = $len ) AS PPP
ON P.id = PPP.peticion_id
WHERE P.categoria_id = $id ;"));
what it does is that retrieve all the peticiones who has as many tags in it something like this in SO when filtering by tags.
But as i said i need the eloquent so this is my attempt to recreate the raw query:
$pet = Peticion::whereHas('tags', function($q) use ($tags, $len){
$q->whereIn('tag_id', $tags);
})
->where('categoria_id', '=', $id)
->get();
But it returns me all the peticiones who has this tag OR this tag, OR as many has the $tags array this get achieved with the raw query in the
WHERE PP.conteo = $len
but i dont know how to translate to eloquent.
Hope someone can help me, thanks a lot.