optimize looping mysql result codeigniter mysql php - php

Get the results from follow table max(date)
leads table
id name
75943 name1
82501 name2
lead_follow_up
id lead_id msg date updated
1 75943 msg1 1438930800 1438884890
2 75943 msg2 1416459600 1415901523
3 82501 msg1 1454713200 1454485087
4 82501 msg1 1439362800 1438564891
using the following query i get result
$today_date = mktime(0, 0, 0, $mon, $day-1, $year);
SELECT * FROM (`lead_follow_up`) LEFT JOIN `leads` ON `leads`.`id` = `lead_follow_up`.`lead_id` WHERE `date` <= $today_date GROUP BY `lead_follow_up`.`lead_id` ORDER BY `lead_follow_up`.`date` DESC
from the above query i get array $previou
$previou= Array
(
[0] => stdClass Object
(
[id] => 1
[lead_id] => 75943
[date] => 1438930800
[updated_on] => 1438884890
)
[1] => stdClass Object
(
[id] => 2
[lead_id] => 75943
[date] => 1416459600
[updated_on] => 1415901523
),
[2] => stdClass Object
(
[id] => 3
[lead_id] => 75943
[date] => 1416459600
[updated_on] => 1415901523
),....etc
);
foreach($previou as $key => $p):
$q = "SELECT `id` FROM (`lead_follow_up`) WHERE `lead_id` = '".$p->id."' AND `date` > '".$p->date."' ORDER BY `updated_on` DESC ";
if(!$this->db->query($q)){
$previouData[$key] = $p;
$pCount++;
}
endforeach;
What I'm really expecting to see is data like
id lead_id name msg
1 75943 name1 msg1
any help to optimize this in single query

Related

SQL query to group results based on field

I have a table has 4 fields columns; id, cinema_id, movie_id, showing_at.
id - Integer(primary key)
cinema_id - Integer(foreign key)
movie_id - Integer(foreign key)
showing_at - Datetime
Am trying to come up with a query that retrieves the result from table based on the movie_id column and a date, and groups the results using the cinema_id;
My current query looks like this using laravel
$models = DB::table('showtimes')->where('movie_id', $movie_id)
->whereBetween('showing_at', [$date." 00:00", $date." 23:00"])
->groupBy('cinema_id')
->get();
The dumped query result looks like this
Array
(
[0] => stdClass Object
(
[id] => 161
[cinema_id] => 1
[movie_id] => 15
[showing_at] => 2016-03-20 12:20:00
[created_at] =>
[updated_at] =>
)
[1] => stdClass Object
(
[id] => 145
[cinema_id] => 3
[movie_id] => 15
[showing_at] => 2016-03-20 10:00:00
[created_at] =>
[updated_at] =>
)
)
How do i query the db to group all the showtimes under cinema_id

How to get the most favourited items, from another table?

So, there's the User model, and the Item model. It's a many-to-many relation: an item can belong to many users, and a user can have many items. Therefore, there's the UserItemRel model.
To summarize:
item
id
name
date_created
date_updated
user
id
email
password
date_created
date_updated
user_item_rel
user_id
item_id
date_created
My query, before making the switch to Yii2, was this:
SELECT COUNT(UIR.`user_id`) as `favourited`, IT.`id`, IT.`name`, CA.`name` as `category`
FROM `user_item_rel` UIR
LEFT JOIN `item` IT ON UIR.`item_id` = IT.`id`
LEFT JOIN `category_item` CI ON UIR.`item_id` = CI.`item_id`
LEFT JOIN `category` CA ON CI.`category_id` = CA.`id`
WHERE UIR.`date_created` >= (SYSDATE() - INTERVAL 3 YEAR)
GROUP BY UIR.`item_id`
ORDER BY
`favourited` DESC
LIMIT 20
I've used the yii2-enhanced-gii extension to generate the models.
I want to show the 20 most favourited items in the past 48 hours, with their counts. I'm migrating from Yii1.1, and it's been quite the ride so far, and I can't figure this out.
I've found
$this->hasMany(UserItemRel::className(), ['id' => 'user_id'])
->viaTable('user_item_rel', ['id' => 'item_id'], function ($query) {
$query->andWhere(['date_created < INTERVAL 2 DAY'])
->orderBy(['COUNT(*)' => SORT_DESC]);
});
}
but how to properly use this?
The query would something like bellow. I would try to run a native query instead of trying to find out how this could be done withing the orm.
SELECT item_id, item.name, count(*) favorite
FROM user_item_rel
LEFT JOIN user ON user.id = user_item_rel.user_id
LEFT JOIN item ON item.id = user_item_rel.item_id
WHERE user_item_rel.date_created >= (sysdate() - interval 2 DAY)
GROUP BY item_id, name
ORDER BY favorite DESC
LIMIT 20
You might be able to try something like this:
$items = UserItemRel::find()
->asArray()
->select("COUNT(`user_id`) as favourited, `item_id`")
->groupBy("item_id")
->joinWith("item")
->orderBy("favourited DESC")
->indexBy("item_id")
->where("'date_created' >= '".date("Y-m-d", strtotime("-2 days"))."'")
->limit(3)
->all();
In my testing it gives me something like this:
Array
(
[1] => Array
(
[favourited] => 4
[item_id] => 1
[item] => Array
(
[id] => 1
[name] => Donec
[date_created] => 2015-08-26
[date_updated] => 2015-08-26
)
)
[8] => Array
(
[favourited] => 3
[item_id] => 8
[item] => Array
(
[id] => 8
[name] => Tellus
[date_created] => 2015-08-26
[date_updated] => 2015-08-26
)
)
[7] => Array
(
[favourited] => 2
[item_id] => 7
[item] => Array
(
[id] => 7
[name] => Mollis
[date_created] => 2015-08-26
[date_updated] => 2015-08-26
)
)
)

Get the highest value of array query mysql, php

With a big Thanks to others here i get this query now. its working fine, but i would need to get just the highest value of the post_id (how_many). it seems not possible to set a MAX(count(*)) on that. so how could i change this to get only the highest count by every id? i just need the value of every id where count == highest. how could i do this? thanks for any help.
$test = $wpdb->get_results('select
posts_id, value,count(*) as how_many
From wp_mrp_rating_item_entry_value
group by
posts_id, value
order by count(*) desc');
echo '<pre>';
print_r($test);
echo '</pre>';
i would need something like order by MAX((count(*)) or MAX((count(how_many))
i already read this but i dont know how to use this for my purpose Filtering log file using COUNT, GROUP BY, ORDER BY MAX
this is an example of the output i get now. so number 1 should not appear because number [0] has been voted 2 times. (how_many). i just need every id 1x in the output. no id shouldt appear twice or more. cause just the highest count is needed. thanks and sorry for the bad english.
Array
(
[0] => stdClass Object
(
[posts_id] => 336
[value] => 8
[how_many] => 2
)
[1] => stdClass Object
(
[posts_id] => 336
[value] => 7
[how_many] => 1
)
[2] => stdClass Object
(
[posts_id] => 380
[value] => 5
[how_many] => 1
)
[3] => stdClass Object
(
[posts_id] => 378
[value] => 7
[how_many] => 1
)
[4] => stdClass Object
(
[posts_id] => 329
[value] => 2
[how_many] => 1
)
[5] => stdClass Object
(
[posts_id] => 327
[value] => 3
[how_many] => 1
)
)
You can filter the resulting groups in a HAVING clause based on a match against a subquery for the maximal count:
SELECT posts_id, value, COUNT(*) AS how_many
FROM wp_mrp_rating_item_entry_value t1
GROUP BY posts_id, value
HAVING how_many = (
SELECT COUNT(*)
FROM wp_mrp_rating_item_entry_value t2
WHERE t2.posts_id = t1.posts_id
GROUP BY t2.value
ORDER BY COUNT(*) DESC
LIMIT 1
)

How to count the number of same values in php or mysql

p1 p2 p3 p4 p5 p6 p7 p8
---------------------------------------------------------------------------------------
1414 1414 1417 1417 1422,1421 1422,1421 1422,1421 1422,1421
The above table has 8 columns in which the adjacent columns having same values. How to count the number of columns based on the column values in php or in mysql..
For Eg :
for 1414---values are p1,p2 and count is 2
for 1422,1421--- values are p5,p6,p7,p8 and count is 4.
Can any one help me in this..
Array
(
[0] => Array
(
[period] => p1
[subject] => 1434
[nop] => 1
)
<b>
**[1] => Array
(
[period] => p2
[subject] => 1440,1439
[nop] => 1
)
[2] => Array
(
[period] => p2,p3
[subject] => 1440,1439
[nop] => 2
)**
</b>
[3] => Array
(
[period] => p2,p3,p4
[subject] => 1440,1439
[nop] => 3
)
[4] => Array
(
[period] => p5
[subject] => 1442
[nop] => 1
)
[5] => Array
(
[period] => p6
[subject] => 1442
[nop] => 1
)
[6] => Array
(
[period] => p7
[subject] => 1442
[nop] => 1
)
)
I have got the above array.. how to remove the above highlighted values in the above array from it.
suppose your $row has reesult of table
$your_val = '1414'; // for eg 1414
$result_col = ""; // will contain you columns
$result_count = 0; // will contain your count
// $row has the each column value when you fetch from database eg $row['p1'] = 1414
foreach($row as $key=>$val)
{
if($val==$your_val)
{
$result_count += 1;
if($result_text=="")
{
$result_col = $key;
}
else
{
$result_col = $result_col.",".$key;
}
}
}
echo "values are ".$result_col." and count is ".$result_count; // output
You can do it with MySQL:
SELECT
IF(p1='1414',1,0) + IF(p2='1414',1,0)+ IF(p3='1414',1,0) + IF(p4='1414',1,0) + IF(p5='1414',1,0) + IF(p6='1414',1,0) + IF(p7='1414',1,0) + IF(p8='1414',1,0) AS cnt
FROM your_table;
If you are using PHP to access the databasem, you can replace the '1414' with a variable to count the occurences of the variable's value.

MySQL count complex query results?

I have the following query:
$count = (SELECT COUNT(*) FROM post GROUP BY ID
HAVING ID NOT IN (SELECT taxiID FROM taxi WHERE userID = '.$userID.' AND value IS NOT NULL)
ORDER BY postID), OBJECT);
Count contains this:
count = Array ( [0] => stdClass Object ( [COUNT(*)] => 1 ) [1] => stdClass Object ( [COUNT(*)] => 1 ) [2] => stdClass Object ( [COUNT(*)] => 1 ) [3] => stdClass Object ( [COUNT(*)] => 1 ) [4] => stdClass Object ( [COUNT(*)] => 1 ) [5] => stdClass Object ( [COUNT(*)] => 1 ) [6] => stdClass Object ( [COUNT(*)] => 1 ) [7] => stdClass Object ( [COUNT(*)] => 1 ) [8] => stdClass Object ( [COUNT(*)] => 1 ) [9] => stdClass Object ( [COUNT(*)] => 1 ) [10] => stdClass Object ( [COUNT(*)] => 1 ) [11] => stdClass Object ( [COUNT(*)] => 1 ) [12] => stdClass Object ( [COUNT(*)] => 1 ) [13] => stdClass Object ( [COUNT(*)] => 1 ) [14] => stdClass Object ( [COUNT(*)] => 1 ) [15] => stdClass Object ( [COUNT(*)] => 1 ) [16] => stdClass Object ( [COUNT(*)] => 1 ) [17] => stdClass Object ( [COUNT(*)] => 1 ) [18] => stdClass Object ( [COUNT(*)] => 1 ) [19] => stdClass Object ( [COUNT(*)] => 1 )
I need to count the number of results delivered by the above. Thing is, I have no idea how to use the result!
I had this code but now it won't work:
<?php if($count[0]->{'COUNT(*)'} > 10){ ?
echo "Load More";
}else {
echo "Nothing to load";
} ?>
$count should be more than 10 and my php should echo Load More but it is echoing Nothing to load.
The taxi table looks like this:
ID taxiID userID value
1 1 1 1
2 1 6 1
3 1 4 0
4 2 1 0
5 2 6 1
6 2 4 0
7 3 6 1
8 3 4 0
The post table looks like this:
ID postID randomNum
1 1 564
2 2 789
3 3 234
4 4 845
5 5 089
Assuming $userID is 1, the query returns postID 1,3,4,5 (1 is liked, 3 is not liked and not disliked by user 1, 4 and 5 are not liked and not disliked by any user). Therefore $count should contain 4 (4 results are found).
If my query is inefficient, how do I adapt it to be efficient?
Ultimately, the question is how do I do something like:
if ($count > 10) {}
Your problem is, your query isn't returning what you think it returns (it always helps to run you query standalone, to see if the result set is what you expect).
Right, let's break this down.
It is counting all posts that the user has not liked or disliked. likes and dislikes are stored in the taxi table. taxi.taxiID matches post.ID. Hence if the userID with any value that isn't null is found, ignore that post.ID. I am counting those post.ID which are not ignored
You're trying count all posts that don't have a matching record in the taxi table, for that userID. What you want here is to JOIN the tables and get those rows in post that would normally be excluded by the join. This is achieved by an left outer join
(edited)
SELECT p.ID, t.taxiID
FROM post p LEFT OUTER JOIN taxi t ON p.ID = t.taxiID AND t.userID = '.$user.'
HAVING t.taxiID IS NULL
That HAVING clause is saying: only those rows in the resultset that didn't have a corresponding t.taxiID.
If you run this query and get the expected set of rows (posts that do not have likes or dislikes by that user) THEN you can add an outer query to count the number of returned rows:
SELECT COUNT(*) as count FROM (
SELECT p.ID, t.taxiID
FROM post p LEFT OUTER JOIN taxi t ON p.ID = t.taxiID AND t.userID = '.$user.'
HAVING t.taxiID IS NULL
) a
This should return a single scalar named count. In this case you'll be able to say:
if ($count[0]->count > 10) { blah blah blah }
(2nd edit) This inner query will get you those posts that have either value = 1 in the taxi table, or no value at all, which results in 4 being returned for your example:
SELECT p.ID, t.taxiID, t.value
FROM post p LEFT OUTER JOIN taxi t ON p.ID = t.taxiID AND t.userID = '.$user.'
HAVING t.taxiID IS NULL OR t.value = 1
In case you want to know how many results would have been returned WITHOUT the LIMIT clause, according to the MySQL documentation:
A SELECT statement may include a LIMIT clause to restrict the number
of rows the server returns to the client. In some cases, it is
desirable to know how many rows the statement would have returned
without the LIMIT, but without running the statement again. To obtain
this row count, include a SQL_CALC_FOUND_ROWS option in the SELECT
statement, and then invoke FOUND_ROWS() afterward:
mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
-> WHERE id > 100 LIMIT 10;
mysql> SELECT FOUND_ROWS();
http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_found-rows
SELECT COUNT(*) FROM post
WHERE postID NOT IN
( SELECT taxiID
FROM taxi
WHERE userID = '.$userID.'
AND value = 0
)
ORDER BY postID;
SELECT COUNT(*) FROM post
WHERE postID NOT IN
( SELECT taxiID
FROM taxi
WHERE userID = '.$userID.'
AND value = 0
)
Can you also provide us with the error message if this does not work?
Why not this?
SELECT COUNT(*) FROM post
WHERE postID NOT IN (
SELECT taxiID FROM taxi
WHERE userID = '.$userID.' AND value = 0
)
LIMIT 10
Note there is no need to perform an order by if you are only looking for the count. Also note you have a limit there so the result won't have more than 10 records. Not sure if that is the idea.
I found the answer and it was dead simple:
if (count($count) > 10) {}

Categories