I have 2 table duty_sheets
centerId | centerName | p1 | p2 | p3 | p4 | ...p22 | examiId
1 | xyz | 1 | 5 | 8 | 7 | 1 | 1
2 | abc | 9 | 1 | 6 | 6 | 1 | 1
and feedback
id | centerId | inspectorId | A | B | C | examiId
1 | 1 | 1 | 1 | 5 | 8 | 1
2 | 2 | 9 | 9 | 1 | 6 | 1
here is my code
$center = DutySheet::select('duty_sheets.centerId', 'duty_sheets.centerName','feedback.id')
->leftJoin('feedback', function ($leftJoin) {
$leftJoin->on('duty_sheets.examId', 'feedback.examId')
->where("duty_sheets.centerId", 'feedback.centerId')
->where("feedback.inspectorId", 1);
})
->where("duty_sheets.examId", 1)
->where("p20", 1)
->get();
dd($center);
to retrieve "All rows from DutySheet where p20 = 1 and dutysheet.examId = 1, and relevant rows from feedback depend on centerId, inspectorId and examId.
The problem is that the query return feedback.id as null while the record exist in feedback table with the ids.
Laravel version = 9
The problem is in left Join
->where("duty_sheets.centerId", 'feedback.centerId')
This build a where against the value 'feedback.centerId'
duty_sheets.centerId='feedback.centerId'
You need use
->on("duty_sheets.centerId",'=', 'feedback.centerId')
Or
->whereColumn("duty_sheets.centerId", 'feedback.centerId')
I am trying to get the count of unique batches in gift_code table for each campaign. The gift_code table is joined to campaign table by campaign_id.
Here is some sample data for campaign table.
--------------+--------------
|campaign_id | name |
--------------+--------------
| 1 | abc |
--------------+--------------
| 2 | xyz |
--------------+--------------
Below is some sample data for gift_code table.
--------------+------------------------+--------------+
|gift_code_id | campaign_id | batch | unique_code |
--------------+-------------+----------+---------------
| 1 | 1 | 1 | zxc23 |
--------------+-------------+----------+--------------+
| 2 | 1 | 2 | rtc26 |
--------------+-------------+----------++-------------+
| 3 | 2 | 1 | z8723 |
--------------+-------------+----------+--------------+
| 4 | 2 | 2 | h7c26 |
--------------+-------------+----------++-------------+
| 5 | 2 | 2 | rrcf6 |
--------------+-------------+----------++-------------+
| 6 | 2 | 3 | r7y28 |
--------------+-------------+----------++-------------+
| 7 | 2 | 3 | bnc26 |
--------------+-------------+----------++-------------+
$campaign = DB::table('campaign')
->select('campaign.*', DB::raw('count(gift_code.batch) as batch_count')->groupBy('gift_code.campaign_id')->groupBy('gift_code.batch'))
->leftjoin('gift_code', 'campaign.campaign_id', '=', 'gift_code.campaign_id')
->get();
My expected results are:
--------------+-------------------------+
|campaign_id | name |batch_count|
--------------+-------------+-----------+
| 1 | abc | 2 |
--------------+-------------+-----------+
| 2 | xyz | 3 |
--------------+-------------+-----------+
Try below query
$data = \DB::table('campaign as c')
->leftJoin('gift_code as gc','c.campaign_id','=','gc.campaign_id')
->select('c.*',\DB::raw('COUNT(distinct(gc.batch)) as batch_count'))
->groupBy('c.campaign_id')
->get();
Having a hive table with age column consisting of age of persons.
Have to count and display the top 3 age categories.
Ex: whether below 10, 10-15, 15-20, 20-25, 25-30, ...
Which age category appears more.
Please suggest me a query to do this.
select case
when age <= 10 then '0-10'
else concat_ws
(
'-'
,cast(floor(age/5)*5 as string)
,cast((floor(age/5)+1)*5 as string)
)
end as age_group
,count(*) as cnt
from mytable
group by 1
order by cnt desc
limit 3
;
You might need to set this parameter:
set hive.groupby.orderby.position.alias=true;
Demo
with mytable as
(
select floor(rand()*100) as age
from (select 1) x lateral view explode(split(space(100),' ')) pe
)
select case
when age <= 10 then '0-10'
else concat_ws('-',cast(floor(age/5)*5 as string),cast((floor(age/5)+1)*5 as string))
end as age_group
,count(*) as cnt
,sort_array(collect_list(age)) as age_list
from mytable
group by 1
order by cnt desc
;
+-----------+-----+------------------------------+
| age_group | cnt | age_list |
+-----------+-----+------------------------------+
| 0-10 | 9 | [0,0,1,3,3,6,8,9,10] |
| 25-30 | 9 | [26,26,28,28,28,28,29,29,29] |
| 55-60 | 8 | [55,55,56,57,57,57,58,58] |
| 35-40 | 7 | [35,35,36,36,37,38,39] |
| 80-85 | 7 | [80,80,81,82,82,82,84] |
| 30-35 | 6 | [31,32,32,32,33,34] |
| 70-75 | 6 | [70,70,71,71,72,73] |
| 65-70 | 6 | [65,67,67,68,68,69] |
| 50-55 | 6 | [51,53,53,53,53,54] |
| 45-50 | 5 | [45,45,48,48,49] |
| 85-90 | 5 | [85,86,87,87,89] |
| 75-80 | 5 | [76,77,78,79,79] |
| 20-25 | 5 | [20,20,21,22,22] |
| 15-20 | 5 | [17,17,17,18,19] |
| 10-15 | 4 | [11,12,12,14] |
| 95-100 | 4 | [95,95,96,99] |
| 40-45 | 3 | [41,44,44] |
| 90-95 | 1 | [93] |
+-----------+-----+------------------------------+
Hi I want query from 3 table
user:
+----+-----------+
| id | name |
+----+-----------+
| 1 | Denny |
| 2 | Agus |
| 3 | Dini |
| 4 | Angel |
+----+-----------+
History_Education
+----+-----------+-------------+
| id | userId | educationId |
+----+-----------+-------------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 1 |
| 4 | 2 | 2 |
+----+-----------+-------------+
Education
+----+-----------+----------+
| id | level | Name |
+----+-----------+----------+
| 1 | 1 | SD |
| 2 | 2 | SMP |
| 3 | 3 | SMA |
| 4 | 4 | S1 |
+----+-----------+----------+
How to query with laravel Eloquent to get the latest user education order by Level DESC
expected:
+----+-----------+----------------------+
| id | Name | Latest_Education |
+----+-----------+----------------------+
| 1 | Denny | SMP |
| 2 | Agus | SMP |
| 3 | Dini | - |
| 4 | Angel | - |
+----+-----------+----------------------+
In normal query:
select id,name ,(select E.name from education E inner join History_eductaion HE on E.id = HE.education_id where HE.userId =U.id limit 1 order by E.level DESC )latest_education from USER U
How to translate to laravel eloquent?
The quick answer is use the query builder - your query needed to be altered slightly to match the table names and columns as listed in your question:
$result = DB::table('user')
->select([
'id',
'name',
DB::raw("(select E.name from Education E inner join History_Education HE on E.id = HE.educationId where HE.userId = user.id order by E.level DESC limit 1) as latest_education")
])
->get();
I have two tables A1,A2
A1 (primary key ID):
| ID | NAME |
|-------|---------|
| 1 | Cat1 |
| 2 | Cat2 |
| 3 | Cat3 |
| 4 | Cat4 |
| 5 | Cat5 |
and A2 (primary key ID, foreign key A1_ID=A1.ID)
| ID | NAME | A1_ID | TYPE |
|-------|---------|--------|--------|
| 1 | Sub1 | 1 | L |
| 2 | Sub2 | 2 | F |
| 3 | Sub3 | 3 | V |
| 4 | Sub4 | 4 | L |
| 5 | Sub5 | 4 | V |
| 6 | Sub6 | 5 | |
I am trying to get all the results from both tables where A2.Type is L or F or null
This is what I have up to now:
select a.*, b.*
from a1 a
left join a2 b
on a.id=b.a1_id
where (b.type='L'
or b.type='F'
or b.type is null)
which returns :
| ID | NAME | ID | NAME | A1_ID | TYPE |
|-------|---------|--------|--------|--------|--------|
| 1 | Cat1 | 1 | Sub1 | 1 | L |
| 2 | Cat2 | 2 | Sub2 | 2 | F |
| 4 | Cat4 | 4 | Sub4 | 4 | L |
| 5 | Cat5 | 6 | Sub6 | 5 | |
But I am looking for a query that it will exclude the line with A1.ID = 4 because with the same A1_ID there is a row with TYPE=V
| ID | NAME | ID | NAME | A1_ID | TYPE |
|-------|---------|--------|--------|--------|--------|
| 1 | Cat1 | 1 | Sub1 | 1 | L |
| 2 | Cat2 | 2 | Sub2 | 2 | F |
| 5 | Cat5 | 6 | Sub6 | 5 | |
Any ideas?
You can do this with not exists:
select a.*, b.*
from a1 a left join
a2 b
on a.id = b.a1_id
where (b.type = 'L' or b.type='F' or b.type is null) and
not exists (select 1 from a2 where a2.id = a.id and a2.type = 'V');
Your original query doesn't quite do what your text says. This seems to be what you are describing:
select a.*, b.*
from a1 a join
a2 b
on a.id = b.a1_id and
(b.type = 'L' or b.type='F' or b.type is null)
where not exists (select 1 from a2 where a2.id = a.id and a2.type = 'V');
That is, the conditions in the where clause are moved to the on clause and the join is changed to an inner join. The difference is when there are no matches in a2 for a given id. Your version would return the row. This version will filter it out.
select a.*, b.*
from a1 a
left join a2 b
on a.id=b.a1_id
left join a2 c
on c.a1_ID = b.a1_ID AND c.type = 'V'
where (b.type='L'
or b.type='F'
or b.type is null)
and c.type is null
This is one way. If all you ever need to consider is v this should be efficient. However, if you need to adjust based on other criteria there maybe a better way.
in essence this takes your current results and compares it to another set of a2 that only contains record type "V". If any match is found, it is excluded from the results.