Codeigniter correct JOIN request - php

I have 2 tables with next construction & data:
Table 1 - events:
id name about owner_id
1 Event1 <description> 2
2 Event2 <description> 1
3 Event3 <description> 2
4 Event4 <description> 2
And table 2 - event_follows
id event_id user_id
1 1 2
2 4 2
I need to get all events for current user (i.e. user with id 2) and join count of followers for this event. Now I'm using this code:
$this->db->select('events.*, COUNT(event_follows.id) as followers')
->from('events')
->where('events.owner_id', $id); // $id - equals 2
$this->db->join('event_follows', 'event_follows.event_id = events.id', 'left')
->group_by('event_follows.event_id');
All seems to be ok, but there is a problem. This code returns only 2 events of 3 - events with id 1 & 4. As I understand, this happens because there is no followers for event 3.
So how to correctly fetch all events and get count of it's followers, including those that have 0 followers?

In order to get all rows from the events table you need to group by events.id as opposed to event_follows.event_id
$this->db->select('events.*, COUNT(event_follows.id) as followers')
->from('events')
->where('events.user_id', $id); // $id - equals 2
$this->db->join('event_follows', 'event_follows.event_id = events.id', 'left')
->group_by('events.id'); //change to events.id

Related

mysql Join showing wrong result PHP

I have following three tables:
taxi:
id shopid taxiId status
1 20 1 1
2 20 2 1
3 20 3 2
4 20 4 1
5 21 1 1
...
preBooking:
id shopid taxiId status
1 20 1 booked
2 20 3 booked
usrBooking:
id shopid taxiId status
1 20 2 booked
2 20 4 booked
Now I want to get all records from taxi table ( for example shop id=20), and matching record of preBooking and usrBooking table.
For example I want to get records like this (if i pass shop id 20 in parameter)
id shopid taxiId preBookingstatus usrBookingstatus
1 20 1 Booked Null
2 20 2 Null Booked
3 20 3 Booked Null
4 20 4 Null Booked
I tried with following code but not working correctly,showing wrong results
$shopid="20";
$this->db->select('t.taxiId,ub.status as usrBookingstatus ,pb.status as preBookingstatus ');
$this->db->from('taxi t');
$this->db->join('usrBooking ub', 'ub.taxiId=t.taxiId','LEFT OUTER');
$this->db->join('preBooking pb', 'pb.taxiId=t.taxiId','LEFT OUTER');
$this->db->where('t.shopid', $shopid);
$this->db->order_by('t.taxiId', 'ASC');
First I am unsure what is this:
$this->db->where('c.salon_id', $shopid);
There is no table "c" in the FROM of the query and "salon_id" is not mentioned in the example data above. This makes the query invalid and you can't run it. Maybe this is the issue. Probably you should change it to:
$this->db->where('t.shopid', $shopid);
Also you are missing some columns in the SELECT. The full query should be:
SELECT t.id, t.shopid, t.taxiId, pb.status as preBookingstatus, ub.status as usrBookingstatus
FROM taxi t
LEFT JOIN usrBooking ub ON ub.taxiId=t.taxiId
LEFT JOIN preBooking pb ON pb.taxiId=t.taxiId
WHERE t.shopid = 20
ORDER BY t.taxiId ASC;
Or with your PHP code:
$shopid="20";
$this->db->select('t.id, t.shopid, t.taxiId, pb.status as preBookingstatus, ub.status as usrBookingstatus');
$this->db->from('taxi t');
$this->db->join('usrBooking ub', 'ub.taxiId=t.taxiId','LEFT OUTER');
$this->db->join('preBooking pb', 'pb.taxiId=t.taxiId','LEFT OUTER');
$this->db->where('t.shopid', $shopid);
$this->db->order_by('t.taxiId', 'ASC');
It seems as if your select statement is missing a few columns. Change
$this->db->select('t.taxiId,ub.status as usrBookingstatus ,pb.status as preBookingstatus ');
to
$shopid=20;
$this->db->select('t.id, t.shopid, t.taxiId,pb.status as preBookingstatus , ub.status as usrBookingstatus ');
$this->db->from('taxi as t');
$this->db->join('usrBooking as ub', 't.taxiId=ub.taxiId','LEFT');
$this->db->join('preBooking as pb', 't.taxiId=pb.taxiId','LEFT');
$this->db->where('t.shopid', $shopid);
$this->db->order_by('t.taxiId', 'ASC');

Joining two mysql tables to get a true/false column

I'm working with PHP and MySql. I'm trying to find a way to select a number of movies from a mysql table, but apart from the movies table I have a watchlist table that stores a userID and the movieID of the movies he/she has added to his/her watchlist:
id userID movieID
=====================================
1 1 3
2 1 5
3 1 7
4 2 3
5 2 2
6 3 2
The movies table looks something like this
movieID title duration
=============================
1 tit1 34:43
2 tit2 35:43
3 tit3 24:43
4 tit4 34:13
5 tit5 11:43
6 tit6 22:43
7 tit7 33:43
The result I'm after is (for example for the user with ID 1):
movieID title duration added
=======================================
1 tit1 34:43 false
2 tit2 35:43 false
3 tit3 24:43 true
4 tit4 34:13 false
5 tit5 11:43 true
6 tit6 22:43 false
7 tit7 33:43 true
Is there a way to join both the movies and the watchlist table to produce the desired result?
Thanks.
You can get the required output by using a LEFT JOIN and then checking for a NULL in the join table.
SELECT m.*, IF(w.id IS NULL, 0, 1) AS added
FROM movies m
LEFT JOIN watchlist w ON (m.movieID = w.movieID AND w.userID = 1)
GROUP BY m.movieID

MySQL pulling content from 2 tables that is connected by a third table

I currently have 2 tables in a database I need to get information from, "content" and "type". These two tables are linked by a 3rd table name "typeMembers." This is the structure:
Table Content:
id content link date isPublished
1 content 1 link 1 3/13/91 1
2 content 2 link 2 3/18/91 1
3 content 3 link 3 3/22/91 1
Table type:
id name
1 Event
2 Page
3 Test
Table typeMember
id type_id content_id
1 1 1
2 2 1
3 3 1
4 1 2
5 1 3
Currently I have my query set up as:
//using PDO in PHP
q = $dbc->prepare(
"SELECT a.id, a.content,a.date,a.link, c.name
FROM content a
LEFT OUTER JOIN typeMember b
ON b.content_id = a.id
LEFT OUTER JOIN types c
ON b.type_id = c.id
WHERE a.isPublished = 1
ORDER BY a.date DESC"
);
$r = $q->execute();
When this is returned I am getting 1 row for each typeMember in the database instead of content. What am I structuring wrong?
Data I would like to be returned:
id content link date name
1 content 1 link 1 3/13/91 Event, Page, Test
2 content 2 link 2 3/18/91 Event
3 content 3 link 3 3/22/91 Event
How it is being returned
id content link date name
1 content 1 link 1 3/13/91 Event
1 content 1 link 1 3/13/91 Page
1 content 1 link 1 3/13/91 Test
2 content 2 link 2 3/18/91 Event
3 content 3 link 3 3/22/91 Event
Edit: filing out the data actually made me realize what is going on. There is a 1 to many relationship with content to type. Is there a way to get all the types in one query?
for get the name in the same row you can use group_Concat
SELECT a.id, a.content, a.date, a.link, group_concat(c.name )
FROM content a
LEFT JOIN typeMember b ON b.content_id = a.id
LEFT JOIN types c ON b.type_id = c.id
WHERE a.isPublished = 1
Group by a.id, a.content, a.date, a.link
ORDER BY a.date DESC

How to get count,type,date with distinct user_id in single query

I created a table in MySQL. It consists of data like this:
Table user_pack:
id type from to user_id current_plan created_ at
1 trail 01-01-2016 05-01-2016 1 0 01-01-2016
2 free 06-01-2016 10-01-2016 1 0 06-01-2016
3 main 11-01-2016 20-01-2016 1 1 11-01-2016
4 main 21-01-2016 29-02-2016 1 1 21-01-2016
5 trail 01-01-2016 29-02-2016 2 1 01-01-2016
6 trail 01-01-2016 05-01-2016 3 0 01-01-2016
7 free 06-01-2016 29-02-2016 3 1 06-01-2016
user_id= 1 =>first register for type=trail it started from = 01-01-2016 to=05-01-2016.in that time current_plan=1 after expired current_plan=0.
=>second register for type=free it started from = 06-01-2016 to=10-01-2016 in that time current_plan=1 after expired current_plan=0.
=>third register for type=main it started from = 11-01-2016 to=20-01-2016 in that time current_plan=1 after expired current_plan=1 only
=>fourth register for type=main it started from = 21-01-2016 29-02-2016 and now it in activation current plan=1.
When I search in between two dates 01-01-2016 and 21-01-2016 with respect to created_at and current plan must be 1 and today date must be in between from and to date in table.
I want the output result in this way:
array0=>['trail count'=>1,'free count'=>0,'main count'=>0,'date'=>01-01-2016]
array1=>['trail count'=>0,'free count'=>1,'main count'=>0,'date'=>06-01-2016]
array2=>['trail count'=>0,'free count'=>0,'main count'=>0,'date'=>11-01-2016]
array3=>['trail count'=>0,'free count'=>0,'main count'=>1,'date'=>21-01-2016]
To be able to perform this type of query you should consider to split up your table into 3 different tables:
pack_type:
id
type
pack_event:
id
pack_type_id
from
to
pack_registration:
id
pack_event_id
user_id
current_plan
created_at
This structure will prevent redundancy and also enables you to make sophisticated queries. It is also important to use date columns for from, to and created_at.
With this table structure you will be able to query all user registrations for the given time period and current_plan=1 with the following query:
select
count(pe.id) as register_count,
pt.type
from
pack_registration pr
cross join pack_type pt
left join pack_event pe on pr.pack_event_id = pe.id and pe.pack_type_id = pt.id
where
pr.current_plan = 1 and
pr.user_id = 1 and
pr.created_at between '2016-01-01' and '2016-01-31'
group by
pt.type

mysql 2 tables updation/deletion based on condition

Hello friends I have 2 Mysql tables with 1:N relationship between category and category_Dates
Category:
ID Category Frequency
1 Cat A Half-yearly
2 Cat B Quarterly
category_Dates:
ID CatID Date
1 1 01-Jan-15
2 1 01-Jul-15
3 2 01-Jan-15
4 2 01-Apr-15
5 2 01-Jul-15
6 2 01-Oct-15
based on the category frequency I am entering number of records automatically in category_date. Eg
When category frequency = quarterly, I am entering 4 records in category_date with ID of that category. And dates will be entered later.
I am little confused if in case on wants to edit the frequency from halfyearly to yearly. How to change number of records. Please help with your valuable suggestions. I am using laravel 4 framework with mysql
best way would be with 3rd table joining Dates and Categories. See little carefully ,you can see its actually Many to Many relationship (N to N) as 1 category can have multiple dates. and one date may be part of multiple categories, like say 01-Jan-15 is part of Category 1 and 2 as well.
So use
category table
id Category Frequency
1 Cat A Half-yearly
2 Cat B Quarterly
date table
id Date
1 01-Jan-15
2 01-Apr-15
3 01-Jul-15
4 01-Oct-15
categories_dates table
ID CatID Date_id
1 1 1
2 1 3
3 2 1
4 2 2
5 2 3
6 2 4
If you change the frequency in Category table, retrieve the update category_id,
delete all from category_dates where CatId=category_id then insert the new entries in category_Dates.
Hope this help.
I assume your models are Category and CategoryDates.
let's update category id 1 from Half-yearlyto to Quarterly
$query = Category::find(1);
$query -> Frequency = 'Quarterly';
$query -> save();
return $query -> id;
in the CategoryDates model you would delete the catID = 1 and insert new data
$catID = 1;
$query = CategoryModel::where('CatId',$catId) -> delete();
$data = ['CatId' => $catID,'date' => 01-Jan-15, ....];
CategoryModel::create($data);
of course assuming that you would return the newly updated category id to your controller and call a funtionn to do the update in your CategoryModel.
Hope this help.

Categories