i wanna make a query to get start date and end date using between,
and start_date & end_date is an input from user so i use syntax like '%'.
here my code, but not working
public function getData()
{
$inputname = Input::get('searchname');
$startdate = Input::get('tglmulai');
$enddate = Input::get('tglsiap');
$name = DB::table('tr_visit')
->join('tm_child','tr_visit.Child_ID','=','tm_child.Child_ID')
->select('tm_child.Child_Name','Bmi_Score')
->where('tm_child.Child_Name', 'LIKE', '%'.$inputname.'%')
->whereBetween('Visit_Date', 'LIKE', '%'.$startdate.'%' and 'LIKE', '%'.$enddate.'%')
->get();
return view('Laporan.Kehadiran.kehadiranview', compact('name'));
}
Please always check the documentation for code examples using the methods you wanted.
Where Between
Notably, the whereBetween http://laravel.com/docs/4.2/queries#advanced-wheres
I havent used that particular method myself, but it looked off so i found the doco and saw this:
$users = DB::table('users')
->whereBetween('votes', array(1, 100))->get();
I cant run your code to be certain, but it seems like this might work for you:
public function getData()
{
$inputname = Input::get('searchname');
$startdate = Input::get('tglmulai');
$enddate = Input::get('tglsiap');
$name = DB::table('tr_visit')
->join('tm_child','tr_visit.Child_ID','=','tm_child.Child_ID')
->select('tm_child.Child_Name','Bmi_Score')
->where('tm_child.Child_Name', 'LIKE', '%'.$inputname.'%')
->whereBetween('Visit_Date', array($startdate, $enddate))
->get();
return view('Laporan.Kehadiran.kehadiranview', compact('name'));
}
This is assuming the ->select() and other methods are work without issue (take out the whereBetween and confirm its working without it first ofcourse).
Wildcards Note
You do realise that '%' is just a wildcard character for LIKE.
It doesn't have anything to do with user input, its just to match any values containing the substring between the '%'.
SQL Wildcards: http://www.w3schools.com/sql/sql_wildcards.asp
DateTime strings in SQL Between
In this situation, you should really be using a datepicker or similar in your html, or be sure to cast the input (which you havent specified the format of) to a format for sql to pick up on.
The SQL Between documentation shows the following example:
SQL Between: http://www.w3schools.com/sql/sql_between.asp
SELECT * FROM Orders
WHERE OrderDate BETWEEN #07/04/1996# AND #07/09/1996#;
So a plain string should work, just be certain its of the same format as the database.
There is some on this (using direct sql) here: SQL query to select dates between two dates
How you achieve this format in the html (or client-side js) is one of many many approaches, but there are many easy to use javascript datepickers out there, even if not using jquery or other library.
Related
Qn in simpler terms: I am searching as a user for other users. All users have set preferred languages and fluent languages. I need to select users whose fluent languages match with this user's preferred languages. Both fluent languages and preferred languages are array (text fields in DB but through JSON cast). How to do that? (Also, fluent language is just one of many conditions in the query. So the query structure itself cannot be modified now.)
Details on what has been tried: I am getting a list of users into $users. One of the conditions require me to compare preferredLanguages (This is an array->collection1) with fluentLanguages (This is also is an array->collection2). All values of preferredLanguages needs to be present in fluentLanguage. So, I am using array_diff and checking if the result is null.
The issue is how do I use this within the where clause? I can use array_diff in, say, an if condition, but I don't know to use it within the where clause.
I tried everything I can think of, but nothing works so far! Can someone please help?
$collection1=$preferrences->preferredLanguages;
$collection2='user_details.fluentLanguages';
$diff= array_diff($collection1, $collection1);
$users->where(function (Builder $query) use ($matchPref) {
$query
->where($diff, '[]'); //I need to check if $diff is null/empty. I tried everything I can think of here.
});
Edit: I tried something else as siggested by Kenny below. I believe this might work but didnt quite solved it yet. Any help is appreciated.
$users->filter(function ($user, $key) use ($preferrences->preferredLanguages)){
return ! array_diff($user['fluentLanguages'], $preferrences->preferredLanguages);
});
I also tried with where but it did not work out as well.
$users->where(array_diff('user_details.fluentLanguages', $preferrences->preferredLanguages)->IsEmpty(), true)
One strategy that comes to my mind could be:
Get the fluentLanguageof each user.
$candidates = User::select('id', 'fluentLanguage')->get();
Filter them according to the condition.
$filtered = $candidates
->filter(function ($candidate, $key) use ($matchFluentIn) {
return ! array_diff($candidate['fluentLanguage'], $matchFluentIn);
})
->pluck('id')
->all();
Get full details of these filetered list of users:
$users = User::whereIn('id', $filtered)->get();
Hope this helps.
What is laravel 5.2 version of the below condition:
->whereDate('created_at', '=', $sel_date)
Please note that $sel_date is in the below format :
$sel_date = date('Y-m-d');
Laravel whereDate method generates the following query:
.... WHERE DATE('created_at') = 'Y-m-d date here'
You can get the same query by using a raw where:
->where(\DB::raw("DATE(created_at) = '".$sel_date."'"));
UPDATE
A good approach is to use bindings in raw queries so the right way to write the query would be this:
->where(\DB::raw("DATE(created_at) = '?'", [$sel_date]));
When the variable $sel_date is created from you in code is not a problem using first approach, but when it is a user input can cause a SQL Injection if you do not use bindings ore do not sanitize user input.
I want to pass the average time and the user e-mail in consoletvs/charts i worte the SQL for that
$currentTime = Carbon::today();
$time_difference = DB::select(DB::raw("SELECT `acu_name` ,AVG(TIMESTAMPDIFF(MINUTE, acu_at, acu_et)) as averageTime
FROM `active_user`
WHERE acu_at <= '$currentTime' GROUP BY `acu_name`"));
in this SQL result is coming when i get this through foreach method but if pass this through charts it's showing an error
$chart = Charts::create('bar', 'highcharts')
->title('Total Clients Average Using Time')
->elementLabel("Total")
->labels($time_difference->acu_name)
->values($time_difference->averageTime)
->responsive(false);
Error Message is :
I can't understand what is the issues please help me to find out the issue
and i attached my database structure and dummy data screen shots.
My php version is 7.3.2
Laravel version is 5.5
When you do DB::select() it gives you array having stdClass objects representing the found rows. So even if you expect one resultant row coming out of your DB::select() query, the result will be still inside an array.
So when you are doing following :
$currentTime = Carbon::today();
$time_difference = DB::select(DB::raw("SELECT `acu_name` ,AVG(TIMESTAMPDIFF(MINUTE, acu_at, acu_et)) as averageTime
FROM `active_user`
WHERE acu_at <= '$currentTime' GROUP BY `acu_name`"));
It is returning an array and inside that there are records matching.
You either need to do foreach() to loop through $time_difference array or do $time_difference[0]-> acu_name
Also, your DB::raw contains a user defined variable which is a danger for SQL injections.
Update :
Please check documentation where there are nice examples for the eloquent way of doing this.
To me it looks indeed strange that this specific error is being thrown. However we can see in you provided code that you store the following in your $time_difference variable:
DB::select(...);
Usually this returns an instance of Illuminate\Database\Query\Builder which is an object if I am not mistaking.
If you take a look into the source code you can see that this function does return $this which is an instance of the above mentioned.
What I can say that is missing is the execution of the query. Usually a select() is followed by a get() or a first() as shown in the documentation.
Another action you should undertake is to validate of anything has been returned after the execution of your query. You final code with some tweaks could look like:
$time_difference = DB::table('active_user')
->select([
'acu_name',
DB::raw('AVG(TIMESTAMPDIFF(MINUTE, acu_at, acu_et)) as averageTime'),
])
->where('acu_at', '<=', $currentTime)
->groupBy('acu_name')
->first(); // Be aware this will only return the first row. Not sure if this is what you inted to do.
if (is_null($time_difference)) {
// Do something when it has not been found.
}
$chart = Charts::create('bar', 'highcharts')
->title('Total Clients Average Using Time')
->elementLabel("Total")
->labels($time_difference->acu_name)
->values($time_difference->averageTime)
->responsive(false);
I am using Laravel
Let's say, I have two date fields in my table. If I want to compare them, i can do whereRaw clause.
$query->whereRaw('date1 > date2')->get()
Is there a way to make a modification to date2 inside this query, so it is actually date2-1day?
Something like:
$query->whereRaw('date1 > (date2-1day)')->get()
You are free to call any SQL code in the "raw" part of your query, so you could do sth like below:
$query->whereRaw('date1 > DATE_SUB(date2, INTERVAL 1 DAY)')->get();
Keep in mind that executing SQL code this way will make your queries work only in databases that support such functions.
Another way would be using whereColumn like
$users = DB::table('users')
->whereColumn('updated_at', '>', 'created_at')
->get();
OR
UserTable::whereRaw('column1 != column2')->get();
In the docs,
$results = DB::select('select * from users where id = ?', array(1));
The Problem
I have a variable $column and $value and I want them to search the database based on what column like this:
$results = DB::select('select * from users where ? LIKE "%?%"', array($column, $value));
But this throws an error:
SQLSTATE[42P18]: Indeterminate datatype: 7 ERROR: could not determine data type of parameter $2 (SQL: SELECT * FROM test WHERE refno LIKE '%te%')
I tried hard-coding the value like this:
$results = DB::select('select * from users where ? LIKE "%te%"', array($column));
but it returns a blank array.
How do I do this? Please help.
EDIT:
The query is actually long (with multiple joins). So I prefer not to use the Query Builder style if possible. But if it's not possible, then I will just use Query Builder.
Info:
Laravel v4.2
PostgreSQL
It could be done in more Query Builder style, like that:
$results = DB::table('users')
->where($column, 'LIKE', '%' . $value . '%')
->get();
EDIT
The only reliable way how to do it with DB::select() is:
$results = DB::select("select * from users where ? LIKE '%?%'", array($column, $value));
It produces the right query, I checked it against the database, but also a blank array, or wrong results. Even if this method somehow worked, you still have to escape table and columns names manually, which is tedious and apparently does not work with ?. If you lets say had a $column named values this method would break, since values is a reserved word (at least in MySQL).
The Query Builder method is highly advised, because it also automatically adds SQL escapes to table and column names. Also it is is more portable across DB drivers. It also supports joins with ease. No need to use the method you wants.
the only way i find working
$phone = '%'.$phone.'%';
$seachbyphone = DB::select('SELECT * FROM user WHERE phoneno LIKE ?',[$phone]);
try this:
use App\User; //don't forget add this to header
$result = User::where('columnName', 'LIKE', "%$value%")->get();
LIKE '%?%'" is incorrect. It must be ? only as sql query only expects ? =>vacancy/placeholder for value. Not any single comma or wildcard.
So You need to add % sign with value not with ? =>(placeholder), and its safe as well.
That's why we need
$results = DB::select("select * from users where ? LIKE ?, [$column, '%'.$value.'%'.]);
I would not recommend DB::select() to anyone, even though you have perfectly valid SQL that works directly in the database engine Laravel produces peculiar errors with made-up error descriptions. Instead use DB::table('my_table')->select('...') instead.