I'm sending data to chartist.js using Laravel controller. When I try to join three tables together to sum the values, the output is essentially doubled when I join the third table.
The following query gets the data I need however doesn't sum them accurately
$chart_stats = Transactions::join('customers', 'customers.id', '=', 'transactions.customer_id')
->join('orders', 'orders.customer_id', '=', 'transactions.customer_id')
->distinct()
->select('customers.region', 'transactions.deposit', 'transactions.purchase_total', 'transactions.finance_amount_paid', 'orders.gov_funding_amount')
->whereIn('customers.region', $selected_regions)
->where('transactions.created_at', '>', $from)
->where('transactions.created_at', '<', $to)
->select(
DB::raw('customers.region as region' ),
DB::raw('sum(transactions.deposit) as deposits'),
DB::raw('sum(transactions.purchase_total) as sums'),
DB::raw('sum(transactions.finance_amount_paid) as finance_paid'),
DB::raw('sum(transactions.deposit+transactions.finance_amount_paid) as total_paid'),
DB::raw('sum(orders.gov_funding_amount) as funding')
)
->groupBy('customers.region')
->orderBy('sums', 'asc')
->get();
This will output the following in an array:
#original: array:6 [▼
"region" => "Region 1"
"deposits" => "5025.40"
"sums" => "52875.00"
"finance_amount_paid" => "0.00"
"total_paid" => "5025.40"
"funding" => "9228.00"
It should be:
#original: array:6 [▼
"region" => "Region 1"
"deposits" => "1706.00"
"sums" => "21271.00"
"finance_amount_paid" => "0.00"
"total_paid" => "1706.40"
"funding" => "3396.00"
I was going to give this as a comment but it would be better as a answer. It's a proposition and I could be wrong. There are 2 possible answers.
Change these lines:
->where('transactions.created_at', '>', $from)
->where('transactions.created_at', '<', $to)
To either:
->whereBetween('transaction.created_at, $from, $to)
Or edit: type, arrays into arrays, corrected:
->where([['transactions.created_at', '>', $from], ['transactions.created_at', '<', $to]])
Methink it is possible, if both conditions are true, the row is selected twice. The distinct() may not do what it is intended to do. You could also try a closure:
->where(function ($query) {
$query->where('transactions.created_at', '>', $from)
->where('transactions.created_at', '<', $to)
->distinct();
})
Related
I have this query:
return DB::table('electricity_meters')
->where('electricity_meters.id', 16)
->leftJoin('service_instances', 'service_instances.electricity_meter_id', '=', 'electricity_meters.id')
->leftJoin('readings', 'electricity_meters.kwh_param_id', '=', 'readings.parameter_id')
->where('readings.taken_at', '>', 'service_instances.active_to')
->select([
'readings.taken_at',
'service_instances.active_to',
])
->get();
Pay attention to 'readings.taken_at', '>', 'service_instances.active_to', but somehow results are...
[
{
taken_at: "2021-02-16 23:59:59",
active_to: "2021-03-28"
},
...
]
what am I missing here?
I think you want to compare between two columns, if that, you should use whereColumn:
return DB::table('electricity_meters')
->where('electricity_meters.id', 16)
->leftJoin('service_instances', 'service_instances.electricity_meter_id', '=', 'electricity_meters.id')
->leftJoin('readings', 'electricity_meters.kwh_param_id', '=', 'readings.parameter_id')
->whereColumn('readings.taken_at', '>', 'service_instances.active_to')
->select([
'readings.taken_at',
'service_instances.active_to',
])
->get();
I've got two tables in my SQL database. Both have a period_from column as the common date format. Both tables have data back dating for several weeks, I've joined my tables, and am selecting the appropriate columns that I need.
Everything works great and gives me the correct data, but as soon as I add whereDate() I get nothing, an empty array. I've tried the bogstandard where() and have also tried targetting my table followed by my column, e.g: *.period_from, not sure why it's not giving me any results here.
$from = Carbon::now()->subDays(14);
$to = Carbon::now();
$order = 'asc';
$data = DB::table('data_source_one as DGA')
->join('data_source_two as DLCA', 'DGA.created_at', '=', 'DLCA.created_at')
->where('event_action', 'Step 1 Loaded: (Loan Details)')
->select('event_count', 'sessions', 'leads', 'DGA.created_at', 'DGA.period_from', 'DGA.period_to')
->whereDate('DGA.period_from', '>=', $from)
->whereDate('DGA.period_to', '<=', $to)
->orderBy('DGA.created_at', $order)
->get();
you can just do this :
$from = Carbon::now()->subDays(14);
$to = Carbon::now();
$order = 'asc';
$data = DB::table('data_source_one as DGA')
->join('data_source_two as DLCA', 'DGA.created_at', '=', 'DLCA.created_at')
->where('event_action', 'Step 1 Loaded: (Loan Details)')
->select('event_count', 'sessions', 'leads', 'DGA.created_at', 'DGA.period_from', 'DGA.period_to')
->where('DGA.period_from', '>=', $from)
->where('DGA.period_to', '<=', $to)
->orderBy('DGA.created_at', $order)
->get();
[
[
[
'condition1',
'value1',
],
[
'condition2',
'value2',
],
[
'condition3',
'value3',
],
],
[
'condition4',
'value4',
],
[
]
]
Im trying to build query builder with values 1 ,values 2, value 3 are in 'or' condition and value 4 in 'and' condition
for first two array i can get the result like what i need
$result = DB::table('table')
->where(function($query) use($value1) {
$query->where('condition1', $value1) // and condition
->orWhere('condition2', $value2) // rest or in or condition
->orWhere('condition3', $value3)
})
->where('condition4', $value4)
->get();
But the array will be keep going. inside the array index 0 is in 'and' condition and a;; other index in or condition
I have tried like
foreach($values as $value){ //
$result->where(function ($qry) use ($value) {
foreach($value as $index=>$val){
$qry->when($index==0),function($qyr){
$qry->where();
}
},function($qry){
$qry->orwhere();
}
});
}
Is there any better solution or improvement i can add?
You should not have condition3 in the grouping query. Normaly it should look like this:
$result = DB::table('table')->where(function($query) use($value1, $value2) {
$query->where('condition1', $value1) // where condition1
->orWhere('condition2', $value2); // or where condition2
})->Where('condition3', $value3) // And where condition3
->get();
I have written a custom related vacancies query for my site, using the plugin WP Job Manager. When using query monitor, I keep getting that the query is very slow (5+ seconds).
I've implemented query caching, except this requires the query to run at least 1 time.
Is it possible to speed up a query like this even more?
$location = get_post_meta($id, '_job_location', true);
$category = get_post_meta($id, 'job_category_wo', true);
$args = array(
'post_type' => 'job_listing',
'numberposts' => 5,
'meta_query' => array(
'relation' => 'OR',
array(
'key' => '_job_location',
'value' => $location,
'compare' => '='
),
array(
'relation' => 'AND',
array(
'key' => '_job_location',
'value' => $location,
'compare' => '='
),
array(
'key' => 'job_category_wo',
'value' => $category[0],
'compare' => 'LIKE'
)
)
)
);
$postslist = get_posts( $args );
In the example you show, you search for posts matching this condition:
_job_location = $region OR _job_location = $region AND job_category_wo LIKE $category[0]
You can simplify this expression to:
_job_location = $region
Boolean algebra says (A) OR (A AND B) is redundant. It's the same as simply (A).
This would factor out the OR operation, which is hard for SQL to optimize.
P.S.: I think there are other mistakes in your example. You set a variable $location but later you use $region. Which is it?
Also you are not sanitizing any values to prevent SQL injection.
["php", "css", "Mysql"]
["html", "css", "js"]
["js","css"]
This is value for 'keywords' field in 3 records
I need search result for this
["php","css"]
ie, result should contain the above 3 record as there is 'php' in 1st record and 'css' in other 2 records
SELECT * FROMjob_postsWHERE JSON_CONTAINS(keywords, '["php","css"]')
only giving the 1st record
array:2 [
0 => "php"
1 => "css"
]
Made use of array instead of json_encoded format($request['keywords] itself)
DB::table('job_posts')
->when($keywords, function ($query) use ( $keywords) {
foreach ($keywords as $key => $value) {
$query->orWhere('keywords', 'LIKE', '%' . $value . '%');
}
}
->get();