Laravel whereNotIn plus whereIn doesn't equal total count - php

How is it possible that whereNotIn() plus whereIn() doesn't equal total count?
Running this:
$updatedBreeds = [
86,
113,
// etc ....
];
DB::enableQueryLog();
dump(Breed::count());
dump(Breed::whereIn('id', $updatedBreeds)->count());
dump(Breed::whereNotIn('id', $updatedBreeds)->count());
dd(DB::getQueryLog());
Returns this:
159
39
0
Am I missing something here? The whereNotIn() call should return 120 results.

Apparently, one of the values in the array was null. Which strangely enough led to this behavior.
Here is a dump on $updatedBreeds:
[
0 => 86
1 => 113
- 2 => null // When I removed this value, the whereNotIn() worked
2 => 44
3 => 8
4 => 54
5 => 54
// ...
]

Related

Count multiple columns with groupBy - laravel

I would like to count two columns in a table and group them in one query. My table:
id
is_correct
question_id
answer_id
1
0
18
67
2
0
18
67
4
1
18
68
2
0
18
67
My queries look like this:
$questions_ids = array(1, 5, 8, 10, 18, 20);
$count_total_answers = $this->whereIn('question_id', $questions_ids)
->select('question_answer_id', DB::raw('count(*) as count_answer_id'))
->addSelect('question_id')
->groupBy(['question_answer_id'])
->get()->toArray();
$count_total_questions = $this->whereIn('question_id', $questions_ids)
->select('question_id', DB::raw('count(*) as count_question_id'))
->groupBy('question_id')
->get()->toArray();
result:
result
I would like to obtain such an array:
array:2 [▼
0 => array:3 [▼
"question_answer_id" => 67
"count_answer_id" => 3
"count_question_id" => 4
]
1 => array:3 [▼
"question_answer_id" => 68
"count_answer_id" => 1
"count_question_id" => 4
]
]
Is this possible in a single query?
Greetings :)

laravel sorting arrays last 5 unique and reverse

I have an array of id's and I want to filter those id's to last 5 and unique ids.
$recently_viewed_ids
array:16 [▼
0 => 1
1 => 2
2 => 1
3 => 2
4 => 8
5 => 7
6 => 6
7 => 6
8 => 6
9 => 5
10 => 8
11 => 4
12 => 1
13 => 1
14 => 1
15 => 1
]
Here is my code and it's messing up because I'm getting 85672
$items = array_slice(array_unique(array_reverse($recently_viewed_ids)), -5);
Output I am expecting
14856
You need to use next combination of array functions:
array_slice( // get first 5 values
array_unique( // get only unique values
array_reverse($arr) //reverse array for get last values
)
,0,5);
Code example here: PHPize.online
In Laravel, I believe you can rewrite the correct answer to:
return collect($arr)
->reverse()
->unique()
->slice(0, 5)
->all();
try this :
$items = array_slice(array_unique(array_reverse($recently_viewed_ids)), 5);

Query Count Monthly of this year - Laravel 5.8

Today is 9/25/2019
I'm trying to query my visitor with in this year of 2019 only.
Then, I want to know how many are on
1,2,3,4,5,6,7,8,9
I've tried
$raw = Visitor::query()
->whereYear('created_at', now()->year -1)
->get()
->pluck('created_at');
$data = [];
foreach ($raw as $i=>$date) {
$data[$i] = Carbon::parse($date)->format('m');
if( Carbon::parse($date)->format('m')[0] != 0 ){
$data[$i] = Carbon::parse($date)->format('m');
}else{
$data[$i] = str_replace('0','',Carbon::parse($date)->format('m'));
}
}
// dd($data);
$dataValues = array_count_values($data);
dd($dataValues);
I got
array:5 [▼
8 => 314
9 => 916
10 => 764
11 => 827
12 => 765
]
Why would I get anything in the future since this month is only September (9) ?
How can I correct it?
I was hoping to get something like this
array:9 [▼
0 => 314
1 => 916
2 => 764
3 => 827
4 => 165
5 => 225
6 => 565
7 => 65
8 => 1265
]
I would like to get an array-like above output.
There are a couple of things you might try.
Laravel automatically makes created_at into a Carbon object, so if you create your query like this:
$raw = Visitor
::whereYear('created_at', \Carbon::now()->year) <<-- Note 2019, not -1 for 2018
->select('created_at')
->get();
Here you get an object with the Carbon date field, created_at. You then won't need to use parse in your if-checks.
I suspect perhaps the answer to your question, though, is that it looks like you are pulling items from 2018, when you want 2019. You have subtracted a year off of this year in your original query.
you should extract month from date then groubby ,and don't forgot select count :
Visitor::whereYear('created_at', Carbon::now()->year)
->select(DB::raw("MONTH(created_at) month"),DB::raw("count('month') as vistors_count"))
->groupby('month')
->get();

Maximum of items a "dump()" on an array will show?

When I dump() a large array after a certain amount of items in the array it will only display something like this: 108 => {#249 …6}. Where ...6 is the number of items in the (sub)array.
As in the code provided you can see that the switching point of this particular array is at key 107. All keys before show all the data and all keys after only show something similar to "{#249 …6}".
Is there a way so display all values of a large array?
106 => {#251 ▼
+"average": 11097598.72
+"date": "2018-06-16"
+"highest": 13999997.93
+"lowest": 6743999.48
+"order_count": 5
+"volume": 5
}
107 => {#250 ▼
+"average": 15222222.0
…5
}
108 => {#249 …6}
109 => {#248 …6}
110 => {#247 …6}

Merge 2 rows into one filling empty fields

So, I have been searching but I could not find something similair.
What I need is to merge 2 rows what I got from DB (stored in an Array) and fill out empty fields.
We have 2 keys FIXED and WEIGHT and they have different values in columns. If we use FIXED type we do not use values from WEIGHT and those columns are empty, now I have to merge those 2 2rows into one.
There is N rows (but always in pair).
Here is example
id type postal fix_price weight_price our_price your_price product_id group_id
1 fixed 8888 50 - 50 - 1 2
2 weight 8888 - 100 - 100 1 2
3 fixed 7777 20 - 20 - 1 2
4 weight 7777 - 30 - 30 1 2
And I need result like below:
id postal fix_price weight_price our_price your_price product_id group_id
1 8888 50 100 50 100 1 2
2 7777 20 30 20 30 1 2
Thank you for helping!
Try:
$collect=array();
$useType='fixed';
foreach($array as $set){
$check=$set['type'];
unset($set['type']);
if(!isset($collect[$set['postal']])) {
$collect[$set['postal']] = $set;
} else {
foreach($set as $k=>$v){
if($k=='id' && $check!=$useType) {
continue;
}
if(!empty($v)){
$collect[$set['postal']][$k] = $v;
}
}
}
}
$collect=array_values($collect);
var_export($collect);
This produces your expacted result, but i dont thing that is what you really want.
I don't really understand how your question is related with the (very different) data structure you shared in your comment under the #JustOnUnderMillions answer, so here is an answer based on the structure suggested by your initial question.
Taking advantage of your other comment where you say "I have tried with $arra1 + $array2" I guess you're able to first format the source data like this:
$fixed = [
8888 => [50, NULL, 50, NULL, 1, 2],
7777 => [20, NULL, 20, NULL, 1, 2],
];
$weight = [
8888 => [NULL, 100, NULL, 100, 1, 2],
7777 => [NULL, 30, NULL, 30, 1, 2],
];
Then it's pretty easy to use this simple code:
foreach ($fixed AS $postal => $fixed_data) {
$weight_data = $weight[$postal];
foreach ($fixed_data AS $key => $fixed_value) {
$all[$postal][$key] = $fixed_value ? $fixed_value : $weight_data[$key];
}
}
which gives the expected result:
echo '<pre>' . print_r($all, TRUE) . '</pre>';
/*
Array
(
[8888] => Array
(
[0] => 50
[1] => 100
[2] => 50
[3] => 100
[4] => 1
[5] => 2
)
[7777] => Array
(
[0] => 20
[1] => 30
[2] => 20
[3] => 30
[4] => 1
[5] => 2
)
)
*/

Categories