Laravel eloquent omits null values - php

I'm trying to do a left join using two tables, where I need to get all user id and name in first which satisfies a condition and total number of rows in the second table for each user. If a user doesn't have a row in the second table, it must be null or zero.
This is my eloquent query.
$users->where('users.access_type', '=', 'type1')->orwhere('users.access_type', '=', 'type2')
->leftJoin(DB::raw("(SELECT user_id, COUNT(*) as count FROM table2 WHERE date > '2014-09-17 16:30:04' GROUP BY user_id) temp_table"), function($leftJoin) {
$leftJoin->on('temp_table.user_id', '=', 'users.user_id');
})->select(DB::raw('users.user_id, users.name, temp_table.count as count'))->orderBy('count')->get();
which doesn't returns the user with null count value. instead it returns the user with least count. I printed the query log and copied the raw query for the above query, filled the values and executed. which works perfectly and also returns the user with null entries. No changes made to the query obtained from query log other than adding the values. Copying the raw query below.
select users.user_id, users.name, temp_table.count as count from `users` left join (SELECT user_id, COUNT(*) as count FROM table2 WHERE date > '2014-09-17 16:30:04' GROUP BY user_id) temp_table on `temp_table`.`user_id` = `users`.`user_id` where `users`.`access_type` = 'type1' or `users`.`access_type` = 'type2' order by `count` asc
I have tried changing the column name of the user_id field for both using as user. Also tries replacing null values with zero using IFNULL. But still no go. Please let me know what am I doing wrong.

In your Eloquent query, you need to replace the last function call ...->first() by ...->get() in order to retrieve all the results instead of only the first one.

Related

How to get a response from a mysqli multi query or how do I get the number of the row sorted in descending order?

I need to run a query with sorting, to get the rating of users, and accordingly show the user his place in the leader-bord.
I found how to execute the query, but I can't figure out how to call it from the code. I get either null or a query error.
$stmAt = $mysqli->multi_query("SET #rank=0;
SELECT RANK FROM
(
SELECT #rank:=#rank+1 AS 'RANK', user_id FROM
(
SELECT score, user_id
FROM `fishing_contest` GROUP BY user_id ORDER BY score DESC
) as t1
) as t2
WHERE user_id = ?";");
$stmAt->bind_param("i", $_SESSION['id']);
$stmAt->execute();
$data = $stmAt->get_result();
$userContest = $data->fetch_assoc();
I have a solution to use a normal query and by assigning a variable and a while loop to output the position, but it is too long. So I would like to know how to use and get a response from queries of this kind?

Eloquent: Get all rows where column value(x) exists in more than one row (SQL DB)

I want to perform the following raw SQL query in Laravel's Eloquent:
SELECT distinct user_id FROM order_payment WHERE user_id IN (SELECT user_id FROM order_payment where payment_status = 'paid' GROUP BY user_id HAVING COUNT(*) > 1);
here I am using where in with property user_id such that all rows in the same table(order_payment) having payment_status=paid and grouped by property user_id having count > 1 are selected and then finally we select distinct user_ids from the given set of user ids.
The overall objective of this query is to get all the rows where required column value(user_id's in this case) > 1...
Ex:
we have 3 rows > A, B, C
row A has user_id = 1;
row B has user_id = 1;
row C has user_id = 2;
result should have [user_id: 1] as the count becomes greater than 1
The above raw query work for me, but now that i am writing a api, I was wondering how this can be replicated in Eloquent.
PLEASE HELP!
So the eloquent way for this query could be done using the groupBy and havingRaw methods
we first select the columns which we need to aggregate
OrderPayment::select('user_id', \DB::raw('COUNT(user_id) as payment_made))
then we groupBy the arribute we need - groupBy('user_id'), Note that the property we group by has to be in the select statement or this wont work.
Now the final clause where we see if there are multiple row having the same user_id, we use > havingRaw('COUNT(user_id) > ?', [1])
Now the overall eloquent query looks like this
OrderPayment::select('user_id', \DB::raw('COUNT(user_id) as payment_made))
->groupBy('user_id')
->havingRaw('COUNT(user_id) > ?', [1])
->get();
Note that in the select clause we are passing the DB raw statement which passes as a string to the query builder and hence one should be careful with SQL injections.

Need help writing an SQL query for a select statement

I need help with an SQL query.
I want to show lines from my test_related_orders table where the current user id equals the user_id in my test_related_orders table and where order_unlock_time (from my table) is <= acutal timestamp. Until here all works fine. But now it gets complicated.
I also need to check/restrict in my wp_posts table if there is an post_author equals to my test_related_orders user_id who has an existing order_number same as from my test_related_orders order_number.
If this statement is true the associated lines from my test_related_orders will be shown. If this statement is false there should be no associated lines.
(So when I delete an order in the woocommerce frontend the statement should'nt return a string for this entry.)
Here is my existing code:
$user_id = get_current_user_id();
//Timestamp for current system time
date_default_timezone_set("Europe/Berlin");
$timestamp = date("Y-m-d H:i:s");
//Database Query
$abfrage = "SELECT * FROM test_related_orders WHERE user_id = '$user_id' AND order_unlock_time <= '$timestamp'";
I think I can use an INNER JOIN and I've tried it here:
INNER JOIN wp_posts ON '$user_id' = post_author WHERE....
but it's to complicated for me as a beginner.
Here are my database structures:
The test_related_orders structure:
The order_number looks like: DE-1016-835 and the user_id as a normal number/id like 1 in this example.
The wp_posts database structure:
The last picture is an example entry from the wp_posts. The problem is that I have to grab the order number from post_title and for this I have to remove the first word "Lieferschein" from this title to get the order_number and there's no extra field for the number...
Thank you for your help! I hope I explained it completely.
First problem to solve is getting the order number from the post_title so that you can compare the values in your inner join. A primitive way of doing this, assuming the order number is always in form AA-DDDD-DDD would be
SELECT right(post_title, 11) as posts_order_number
As you've already discovered, an inner join is what you need, as it'll only return results where the tables match. Note you usually join tables based on their columns, rather than directly comparing to your '$user_id' string (and you've already filtered for this in your where clause).
You can join on more than one field at a time, to match on order number as well as user_id.
Your query now becomes:
SELECT *
FROM test_related_orders tro
INNER JOIN wp_posts p
ON tro.user_id = p.post_author
AND tro.order_number = right(p.post_title, 11)
WHERE tro.user_id = '$user_id' AND order_unlock_time <= '$timestamp'

Laravel Printing out table_1 values that do not exist in table_2

I have 2 databases (AccessControls & User).
AccessControl table has this fields: AC_id, User_id, AccessControls.
User table has this fields: User_id, User_name, UserType.
What I wanted to achieve is:
- Printing out users that has a UserType = 1 (in user table) and User_id which does not exist in AccessControl table.
The results will be stored in a table in my view.blade.php
In the meantime, I managed to get the 1st part, which is users with UserType = 1. However, I have no idea on how I could get the 2nd part, which is to check if the User_id exists in AccessControl table.
Inside my controller:
$user = UserEntry::where('UserType', '=', 1)->get();
I have a rough idea that the query should be something like:
Select statement Where user.User_id != AccessControl.User_id
Any ideas on how I could achieve both parts in a single query?
Either not exists
User::where('UserType',1)
->whereNotExists(function ($q) {
$q->from('AccessControl')
->where('AccessControl.User_id', DB::raw('users.id'));
})
->get();
or leftJoin:
User::where('UserType',1)
->leftJoin('AccessControl','AccessControll.User_id','=','users.id')
->whereNull('AccessControll.id')
->get(['users.*']);
Check performance, suppose left join will be faster.
The SQL way would be a LEFT JOIN in combination with ISNULL():
SELECT
*
FROM
users
LEFT JOIN
AccessControl
ON
user.User_id = AccessControl.User_id
WHERE
users.userType = 1
AND
AccessControl.User_id IS NULL
I'm sure you get this translated to laravel.

MySql - if there is no record, insert multiple rows

Before asking this question, I already search a lot of entries on Google and StockOverflow. Nothing can fulfil my question.
There are two tables - group_sale_bonuses and members. I want to check is already there records with product_id "1" in the group_sale_bonuses.
If not, I want to insert all records from members table into group_sale_bonuses with product_id "1".
My overall requirement is as follow:
IF ((Select count(id) from group_sale_bonuses where product_id = 1) = 0) THEN
INSERT INTO group_sale_bonuses (member_id, product_id, quantity_counter, credit)
SELECT id, 1, 0, 0 FROM members
END IF
But this sql causes the errors.
I know there are solutions about Insert Ignore, Where Not Exists.
But these conditions checking are based on per each record. I have thousands of records in members table. I want to make condition checking just one time like in my above sql example.
By the way, I will use this Sql in Php web application.
You could just set the code in a WHERE clause instead of the IF.
INSERT INTO group_sale_bonuses(
member_id,
product_id,
quantity_counter,
credit)
SELECT
id, 1, 0, 0 FROM members
WHERE(
SELECT
count(id) FROM group_sale_bonuses
WHERE product_id = 1
) = 0;
This should do it for all product_id's
SELECT m.product_id, m.member_id FROM members AS m
LEFT JOIN group_sale_bonuses AS gsb ON gsb.product_id = m.product_id
WHERE gsb.product_id IS NULL ;
You can filter it to a specific product_id by adding to the where clause
SELECT m.product_id, m.member_id FROM members AS m
LEFT JOIN group_sale_bonuses AS gsb ON gsb.product_id = m.product_id
WHERE gsb.product_id IS NULL AND m.product_id = 1;
Take a look at this SQLfiddle: http://sqlfiddle.com/#!2/8482c/2

Categories