How to display latest unique record in mysql codeigniter - php

lets suppose i have 6 records in my table
id | mobile_no | date
-------------------------------------------
1 | 9999999999 | 11-11-2016
2 | 8888888888 | 12-11-2016
3 | 9999999999 | 13-11-2016
4 | 9999999999 | 16-11-2016
5 | 8888888888 | 20-11-2016
6 | 8888888888 | 22-11-2016
Now when i use distinct with mysql query i retrieve :-
id | mobile_no | date
-------------------------------------------
1 | 9999999999 | 11-11-2016
2 | 8888888888 | 12-11-2016
While i want to retrieve :-
id | mobile_no | date
-------------------------------------------
4 | 9999999999 | 16-11-2016
6 | 8888888888 | 22-11-2016
Please help me what query i have to use in codeigniter mysql for access above records??
below is my model query -
$this->db->select('*');
$this->db->from('miscall_records');
$this->db->distinct();
$this->db->group_by('mobnos');
$this->db->order_by("id", "desc");

if you want to use the dataset with the highest ID each, you have to use a different approach.
you have to select the highest IDs for each number first via a GROUP BY with the corresponding aggregation function MAX, and then join the table itself on those keys.
SELECT values.* FROM
(SELECT MAX(id) AS id FROM miscall_records GROUP BY mobile_no) AS keys
LEFT JOIN miscall_records AS values
ON keys.id = values.id

Your expected sql query is :
select a.id, a.mobile_no, a.date from miscall_records a
where a.id = (select max(b.id) from miscall_records b
where b.mobile_no = a.mobile_no) group by a.mobile_no
With Active Records is :
$this->db->select('a.id, a.mobile_no, a.date');
$this->db->from('miscall_records a');
$this->db->where('a.id = (select max(b.id) from miscall_records b where b.mobile_no = a.mobile_no)');
$this->db->group_by('a.mobile_no');
$query = $this->db->get();
Or use only max :
select max(a.id), a.mobile_no, a.date from miscall_records a group by a.mobile_no
Active records :
$this->db->select('max(a.id), a.mobile_no, a.date');
$this->db->from('miscall_records a');
$this->db->group_by('a.mobile_no');
$query = $this->db->get();

You can use group by clause to group values by mobile no. distinct keyword will not work here.

Related

How to count row by using GROUP mysql bind_param?

How to count row by using GROUP mysql bind_param ?
Table : check
.
__________________________
| id | product_id | user |
| 1 | 123 | test |
| 2 | 456 | test |
| 3 | 456 | test |
| 4 | 123 | test |
| 5 | 789 | test |
and this is my code
<?PHP
$username = "test";
$sql = 'SELECT COUNT(*) FROM check WHERE user = ? GROUP BY product_id';
$statement = $db_mysqli->prepare($sql);
$statement->bind_param('s', $username);
$statement->execute();
$result = $statement->get_result();
$row = $result->fetch_row();
$all_product = $row[0];
echo $all_product;
?>
When I test code it's show 5 I want to know how can I do for show 3 group by product_id
You need to change your SQL query.
SELECT COUNT(DISTINCT PRODUCT_ID) FROM check WHERE user = ?
this will produce a result of 3
If you wanted one row for each product, then you would do this:
SELECT product_id, COUNT(*) AS c FROM check WHERE user = ? GROUP BY product_id
which would look like this:
| product_id | c |
| 123 | 2 |
| 456 | 2 |
| 789 | 1 |
Try this query.
$statement=$mysqli->prepare("SELECT user,COUNT(*) FROM check GROUP BY product_id");
I hope it will help you.
you can use one of these three queries as per your need. It will give you results as shown below.
To get the total of rows with distinct product_id present in table-:
SELECT COUNT(DISTINCT product_id) FROM check;
Result-:
COUNT(DISTINCT product_id)
3
To get the rows with distinct product_id row-:
SELECT COUNT(DISTINCT product_id) FROM check GROUP BY product_id;
Result-:
COUNT(DISTINCT product_id)
1
1
1
To get the row with distinct product_id with the count number of duplicate product_id present in the table -:
SELECT COUNT(product_id) FROM check GROUP BY product_id
Result-:
COUNT(product_id)
2
2
1

How to do a result and row that will find the sql sum of two columns?

Table 1 Table 2
_________________ ____________________
| ID| Name |Age | | ID| Cost | Date |
|---|-------|----| |---|-------|-------|
| 1 | Kirk | 33 | | 1 | 10 | 9/10 |
| 2 | Lonzo | 55 | | 1 | 20 | 7/8 |
| 3 | Dave | 44 | | 2 | 12 | 25/7 |
| 3 | 5 | 30/4 |
| 3 | 5 | 4/10 |
I want the result to be Kirk, who is 33, has a total cost of 30 and total dates to 2
etc.. (btw they enter their names and all this comes up)
The sql statement would be like this?
$sql= "SELECT Table1.Name, Table1.ID, Table2.ID, Table1.Age, SUM(Table2.Cost), SUM(Table2.Date)
AS count from Table1, Table2
WHERE Table1.ID = Table2.ID and Table1.Name = (my example here)"
$result = $conn->query($sql);
$Cost = 0;
$Date= 0;
$rec = $result->fetch_assoc();
$Date= $rec{'count'};
$Cost= $rec{'count'};
$Age = $rec{'Age'}
echo "$Name, who is $Age years old a total cost of $Cost and $Date total dates";
Im getting errors, saying my variables are undifined
so how would I put them into variables?
EDIT fixed
instead of using the sql to find it, i used result from a while loop that kept adding one to another variable (to count the date). The cost is able to do in both sql(sum) and result.
instead of using the sql to find it, i used result from a while loop that kept adding one to another variable (to count the date). The cost is able to do in both sql(sum) and result.
You were missing a group clause. I also put that in a subquery and used an INNER JOIN
SELECT Id, Name, Age, Cost, Dates
FROM Table1
INNER JOIN (
SELECT Id i, SUM(Cost) Cost,
COUNT(Date) Dates
from Table2
GROUP BY Id) t
ON i=Id
WHERE Name = 'Kirk'
You should also change one of the php statements to
$Cost= $rec{'Cost'};
Just use join..
SELECT table2.date ,SUM(cost) AS tatol FROM table1
JOIN table2 ON table2.id = table1.id
WHERE table1.id = 1

How to show distinct sender id from conversation

Updated Question:
My private_messages database structure is like this:
+----+-------+-------+-------+--------+------------+
| id | text | byuid | touid | unread | timesent |
+----+-------+-------+-------+--------+------------+
| 1 | Hi | 1 | 4 | 1 | 1514764805 |
| 2 | hello | 1 | 4 | 1 | 1514764804 |
| 3 | hlw | 1 | 4 | 1 | 1514764803 |
| 4 | good | 2 | 4 | 1 | 1514764802 |
| 5 | fine | 3 | 4 | 0 | 1514764801 |
+----+-------+-------+-------+--------+------------+
My all_users_table is:
+----+-------+------+
| id | name | pass |
+----+-------+------+
| 1 | user1 | 123 |
| 2 | user2 | 112 |
| 3 | user3 | 124 |
| 4 | user4 | 258 |
| 5 | user5 | 315 |
+----+-------+------+
My current SQL code is
$sql = "SELECT
a.name, b.id, b.byuid, b.unread, b.starred FROM all_users_table a
INNER JOIN private_messages b ON a.id = b.byuid
WHERE b.touid='4' AND starred='0'
ORDER BY b.timesent DESC, b.unread
LIMIT $limit_start, $items_per_page
";
Which Print Like below:
1
1
1
2
3
All I want is to (For touid = 4)
print all unique byuid as a output.
Order By Unread DESC
Order By timesent DESC
Limit 0, 2 (for pagination purpose)
Output should be:
1
2
Can anyone help me please ? I tried Group By but it shows empty results.
$sql = "SELECT
a.name, b.id, b.byuid, b.unread, b.starred FROM all_users_table a
INNER JOIN private_messages b ON a.id = b.byuid
WHERE b.touid='".$myid."' AND starred='0' GROUP BY a.name
ORDER BY b.timesent DESC, b.unread
LIMIT $limit_start, $items_per_page";
Try this one with GROUP BY CLAUSE
"SELECT
a.name, b.id, b.byuid, b.unread, b.starred
FROM all_users_table a
LEFT JOIN private_messages b ON a.id = b.byuid
WHERE b.touid = '".$myid."' AND starred = '0'
ORDER BY b.timesent DESC, b.unread
LIMIT $limit_start, $items_per_page"
If you need not duplicated rows you should use DISTINCT clause
$sql = "SELECT DISTINCT
a.name, b.id, b.byuid, b.unread, b.starred
FROM all_users_table a
INNER JOIN private_messages b ON a.id = b.byuid
WHERE b.touid='".$myid."' AND starred='0'
ORDER BY b.timesent DESC, b.unread
LIMIT $limit_start, $items_per_page";
(the use of group by for avoid duplicated row in absence of aggregation function as SUM() or MAX() is deprecated in sql and in the most recent version of mySQL generate error)
But looking to your updated data you are not looking for the distinct result but at the result for the most recent sent values
and for this you don't need distinct but a join between al the columns you need and a subselect that retrive the sot recent value for byuid
select a.name, b.id, b.byuid, b.unread, b.starred
FROM all_users_table a
INNER JOIN private_messages b ON a.id = b.byuid A
INNER JOIN (
select byuid, max(timesent) max_sent
from private_messages
WHERE b.touid= 4
group by byuid
) t on t.byuid = b.byuid and t.max_sent = b.timesent
ORDER BY b.timesent DESC, b.unread
LIMIT $limit_start, $items_per_page

Double SQL Query - JOIN

I need a double SELECT sql query from 2 different tables with names visits & items
1.: SELECT visitid, visitdate, visitreason FROM visits WHERE personid = 10
2.: SELECT itemid, itemname, itemtime FROM items WHERE itemvisitid= visitid
I think I need to do a JOIN but don’t know exactly how.
Table examples:
Table: visits
visitid | personid | visitdate | visitreason
1 | 10 | 05/07/2014 | no reason
2 | 10 | 06/07/2014 | some reason
3 | 12 | 06/07/2014 | no reason
4 | 10 | 12/07/2014 | some other reason
Table: items
itemid | personid | itemvisitid | itemname | itemtime
1 | 10 | 2 | box | 23
2 | 10 | 2 | clock | 70
3 | 10 | null | water | 50
4 | 10 | null | paper | 40
5 | 12 | 3 | box | 26
What I have now is this:
$query = "SELECT visitid, visitdate, visitreason FROM visits WHERE personid = '10' ORDER BY visitdate DESC";
// 2nd select: "SELECT itemid, itemname, itemtime FROM items WHERE itemvisitid= visitid";
$db->setQuery($query);
$results = $db->query();
while($row = mysqli_fetch_array($results)){
echo "<tr>
<td>".$row['visitid'].", ".$row['visitdate']."</td>
<td>".$row['visitreason']."</td>
<td>".$row['itemid'].",".$row['itemname'].", ".$row['itemtime']."</td>
</tr>";
}
I need results to be something like this:
<tr>
<td>1, 05/07/2014</td><td>no reason</td><td></td>
<td>2, 06/07/2014</td><td>some reason</td><td>1, box, 23<br />2, clock, 70</td>
<td>4, 12/07/2014</td><td>some other reason</td><td></td>
</tr>
I guess your might to use GROUP_CONCAT like this:
DEMO: http://sqlfiddle.com/#!2/9d4e22/15
SELECT visitid, DATE_FORMAT(visitdate,'%m/%d/%Y'), visitreason,
GROUP_CONCAT(itemid,itemname, itemtime)
FROM visits left join items on visits.visitid = items.itemvisitid
WHERE visits.personid = 10
GROUP BY visitid, visitdate, visitreason
You might want to read this to know GROUP_CONCAT :
How to use GROUP_CONCAT in a CONCAT in MySQL
The document of GROUP_CONCAT() is here:
http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat
hope this helps.
SELECT `visits`.`visitid`, `visits`.`visitdate`, `visits`.`visitreason`,`items`.`itemname`, `items`.`itemtime` from `visits` INNER JOIN `items` ON `visits`.`personid`=`items`.`personid` WHERE `visits`.`personid` = '10' ORDER BY `visits`.`visitdate` DESC
if there is any error please change the field name personid in 'items' table.and then check.
This query:
SELECT v.visitid,
v.visitdate,
v.visitreason,
i.itemid,
i.itemname,
i.itemtime
FROM visits v
INNER JOIN items i
ON ( v.visitid = i.itemvisitid )
WHERE v.person_id = 10
ORDER BY v.visitdate DESC,
i.itemid ASC
will link both tables and produce a resultset that you can traverse using a double loop. The outer loop to process changes to the visit, and the inner to add every item visited in a particular visit.

what to add in where clause to get the desired result?

I am trying to get max(date) ,count(id) and *look_name for max(date)* from this table:
id | member_id | look_week | look_name | is_pinned | date
1 | 1 | 3 | the improviser | yes | 2013-11-19 21:57:04
2 | 1 | 2 | destined for stardom | yes | 2013-11-19 21:56:00
2 | 1 | 1 | fashinably corporate | no | 2013-11-19 21:54:00
This is my query:-
$sql="SELECT COUNT(id) as total_pins,MAX(pinned_date) as last_activity_date FROM pin_info WHERE member_id='1' AND is_pinned='yes'";
I am getting this array as out put.
//[total_pins] => 2
//[last_activity_date] => 2013-11-19 21:57:04
//[lookname_for_last_date] => i am stuck at this?
How can I manipulate this query so that i can get look_name for max(date) in this array?
Step 1: First, you have to select the MAX(pinned_date). I assume this is for the one particular member and is_pinned='yes'
Step 2: Then, you have to select the look_name where the pinned_date is equal to the max-date found above. You can do this by making Step 1 and inner query inside Step 2
Step 3: Finally, the query from Step 2 goes as the third column in your main query
SELECT COUNT(*) as total_pins, MAX(pinned_date) as last_activity_date,
(select look_name
from pin_info B
where A.member_id=B.member_id and A.is_pinned=B.is_pinned
and pinned_date in (
select max(pinned_date)
from pin_info C
where B.member_id=C.member_id and B.is_pinned=C.is_pinned
) AS lookname_for_last_date
),
(
select max(pinned_date)
from pin_info C
where A.member_id=C.member_id and A.is_pinned=C.is_pinned
) AS CHK_LAST_DATE
FROM pin_info A
WHERE member_id='1'
AND is_pinned='yes'
To check this, or to tweak it, see this SQL Fiddle here.
most of it is similar..This gives me the exact result.
$sub_query="SELECT MAX(pinned_date) FROM pin_info WHERE member_id='$member_id' AND is_pinned='yes'";
$sql = "SELECT COUNT(*) as total_pins, MAX(pinned_date) as last_activity_date,(SELECT look_name FROM pin_info WHERE member_id='$member_id' AND pinned_date=($sub_query)) as last_pinned_look FROM pin_info WHERE member_id='$member_id' AND is_pinned='yes'";
I'd go for a subselect:
SELECT COUNT(id) as total_pins, MAX(pinned_date) as last_activity_date,
(SELECT look_name FROM pin_info WHERE pinned_date = (SELECT MAX(pinned_date) FROM look_info)) as lookNameForMaxDate
FROM pin_info WHERE member_id='%s' AND is_pinned='yes'

Categories