MySQL Query problem in CodeIgniter - php

So I'm using the following:
$r = new Record();
$r->select('ip, count(*) as ipcount');
$r->group_by('ip');
$r->order_by('ipcount', 'desc');
$r->limit(5);
$r->get();
foreach($r->all as $record)
{
echo($record->ip." ");
echo($record->ipcount." <br />");
}
Standard:
SELECT `ip`, count(*) as ipcount FROM (`soapi`) GROUP BY `ip` ORDER BY `ipcount` desc LIMIT 5;
And I only get the last (fifth) record echo'ed out and no ipcount echoed.
Is there a different way to go around this? I'm working on learning DataMapper (hence the questions) and need to figure some of this out. I haven't quite wrapped my head around the whole ORM thing.
Is there a way to set the count(*) as ipcount without the funny select() statement? I don't think it's triggering for some reason. This could also be a bug in DataMapper, but I'm less certain of that.
Also I found that even if I use the $r->query() method it doesn't return anything except the last entry if I use something like SELECTipFROMsoapiWHERE 1;. It will however return everything (like it should) if I say SELECT * FROM soapi WHERE 1;. If it doesn't have the * it only returns the last line.
Just verified with the new query, anything except selecting all columns (*) only returns the last record. Any help with this would be great. You can craft a statement like select *, count(*) as ipcount but then you still don't have access to it via $record->ipcount.

For your case, once you use COUNT() function in MySQL, it will only return 1 value. Hence you ip result data would not display out.
I suggest you just split this 2 queries.
1. for COUNT(*)
2. for ip
Hope this help.

Related

PHP PDO statement with Sum and other column fails

I'm trying to run an SQL query with PDO
This works
$result = $dbo->query("SELECT sum(c) as scfus
FROM tbl
WHERE
YEAR(ondate)=YEAR('".$_POST['startdate']."')
AND MONTH(ondate)=MONTH('".$_POST['startdate']."')
AND DAY(ondate)=$i");
but this does not
$result = $dbo->query("SELECT a,b,sum(c) as scfus
FROM tbl
WHERE
YEAR(ondate)=YEAR('".$_POST['startdate']."')
AND MONTH(ondate)=MONTH('".$_POST['startdate']."')
AND DAY(ondate)=$i");
The only difference is the addition of the a,b column names to the query.
I can run this query (both of them) directly into mysql and get a single record back, as expected, but PDO does not seem to like column names AND sum in the same query?
I can't see a reason, or solution. New to PDO, so was never an issue for me before.
Thanks.
UPDATE - OK, I still think this should work fine, but as a workaround, I've run 2 sql statements, almost exactly the same. One with SELECT SUM(x), one with SELECT a,b, but without the sum. Works fine, but I really should be able to do it in one statement, unless I'm into some PDO limitation I'm not aware of yet.
you might need to GROUP BY c (or whatever column you may want to group domain aggregate function SUM() by) in order to obtain the desired result-set... and maybe take the suggestion above into account.
Try it this way for your query, worked for me for what you want to achieve :
$result = $dbo->query("SELECT a,b,(SELECT sum(c) as whateverFROM tbl),
as scfus
FROM tbl
WHERE
YEAR(ondate)=YEAR('".$_POST['startdate']."')
AND MONTH(ondate)=MONTH('".$_POST['startdate']."')
AND DAY(ondate)=$i");
SUM returns only one line so you'll never get all your results and only the ones of the first matching WHERE criterias (it registers first record found, then only count what it needs).
It will work
Oh, btw, make a timestamp of the date, make a string of the date post in the date sql format and check
WHERE date = $_POST['date']
will work
SELECT a, b , (SELECT SUM(ID)*30 FROM table) FROM table WHERE ID = SOME(SELECT ID FROM tables WHERE users_ID = idYouWant);

Multiple queries or can be done in one?

I'm not very experienced with more advanced MySQL query stuff.. (mostly basic queries, return and parse response..etc)
However.. I am not clear on the correct approach when I need multiple things (responses) from the database.. Is there a way to get these things from the single query? or do I need to do a new query for each time?
Background:
I use PDO to do a SELECT statement
ie:
$getAllVideos_sql = "SELECT * as FROM $tableName WHERE active IS NOT NULL OR active != 'no' ORDER BY topic, speaker_last, title;";
$getAllVideos_stmt = $conn->prepare($getAllVideos_sql);
$getAllVideos_stmt->execute();
$getAllVideos_stmt->setFetchMode(PDO::FETCH_ASSOC);
$results = $getAllVideos_stmt->fetch(PDO::FETCH_ASSOC);
//parse as I see fit
This gives me my 'chunk of data' that I can pick apart and display as I want.
However.. I want to also be able to give some stats (totals)
For the total (distinct) 'topics'.. as well as total count for the 'titles' (should all be unique by default)
Do I need to do another query, prepare, execute, setFetchMode, fetch all over again?
Is this the proper way to do this? Or is there a way to crib off the initial commands that are already in play?
To be clear, I'm not really looking for a query... I'm looking to understand the proper way one does this.. when they need several pieces of data like I do? multiple queries and executions..etc?
Or maybe it can and -should- be done in one snippet? With an adjustment to the query itself to return sub select/queries info?
this isnt the correct syntax, because it only returns 1 record..(but the total topic count seems to be correct, even though I only get 1 record returned)
SELECT *, count(DISTINCT topic)as totalTopics, count(DISTINCT title)as totalTitles FROM $tableName;
Maybe this the more proper approach? Try to include these totals/details in the main query to pick out?
Hope this makes sense.
Thanks
I don't think you're going to get anything very clean that'll do this, however something like this might work:
SELECT * from $Table t
INNER JOIN (
SELECT COUNT(DISTINCT Topic) as TotalTopics FROM $Table
) s ON 1 = 1
INNER JOIN (
SELECT COUNT(DISTINCT Title) as TotalTitles FROM $Table
) f ON 1 = 1
WHERE ( Active IS NOT NULL ) AND Active != 'no'
Especially with web applications, many people are regularly doing counts or other aggregations somewhere along the way. Sometimes if it is a global context such as all topics for all users, having some stored aggregates helps rather than requerying all record counts every time.
Example. If you have a table with a list of "topics", have a column in there for uniqueTitleCount. Then, based on a trigger, when a new title is added to a topic, the count is automatically updated by adding 1. You can pre-populate this column by doing a correlated update to said "topics" table, then once the trigger is set, you can just have that column.
This also works as I see many times that people want "the most recent". If your system has auto-increment IDs in the tables, similarly, have the most recent ID created for a given topic, or even most recent for a given title/document/thread so you don't have to keep doing something like.
select documentID, other_stuff
from sometable
where documentID in ( select max( documentID )
from sometable
where the title = 'something' )
Use where these make sense then your optimization pull-downs get easier to handle. You could even have a counter per document "title" and even a most recent posting date so they can quickly be sorted based on interest, frequency of activity, whatever.

Mysql query very slow (group by)

mysql query very slow but i use "group by" function...
i remove group by query and query very fast.
How can I solve this problem?
my query code:
$myquery1 = mysql_query("SELECT * FROM konucuklar
WHERE status=''
and category='football'
GROUP BY matchhour
ORDER BY id asc");
while($myquery1record = mysql_fetch_array($myquery1)){
$myquery2 = mysql_query("SELECT * FROM konucuklar
WHERE mactarihi='$bugunt'
and statu=''
and kategori='futbol'
and macsaati='$myquery1record[matchhour]'
ORDER BY id asc");
$toplams=#mysql_num_rows($myquery2);
while ($myquery2record=mysql_fetch_array($myquery2)) {
// code
}
}
}
Your first query does not comply with SQL standards and will be processed by mysql only if strict sql mode is not enabled.
You are issuing the 2nd query in a loop based on the results returned by the 1st query. So, if the 1st query returns 10 rows, then you will execute the 2nd query 10 times. This is very slow. You should rewrite the 2 queries as one, since both queries query the same table and have almost the same where criteria.
No idea what the 2nd while loop does, as I can't see where $listele is defined.
The slow down might not be related to the GROUP BY clause. Try adding an index on columns you need to .
Link to understand index : http://www.tutorialspoint.com/sql/sql-indexes.htm
MySQL Profiling might also help you in your endeavour
Your queries are not optimized and probably could be done better in other way incluiding using only one composed query (JOIN) to fetch all data at once.
Also if your tables have lots of items is good practice to create INDEXES to the fields uses in the common queries for the filter to make the search faster.
Example, your firs select has this complexity (and probably is not well formed)
SELECT * FROM konucuklar WHERE status=''
and category='football'
GROUP BY matchhour
ORDER BY id asc
But is used only to get the matchhour for the second query. The minimal optimization is to use a query to fetch only the required field.
SELECT DISTINCT matchhour FROM konucuklar WHERE status='' and category='football'

Adding count(*) to existing mysql query causes unwanted action in php

$results_ts = mysqli_query($connection, "SELECT id, title, description, content
FROM prose WHERE title LIKE '%$search_title%' LIMIT 10");
if(isset ($_GET['search_title'])){
while($title_arr = mysqli_fetch_array($results_ts)){
echo $title_arr[id]; //and so on...
And that works as I wanted.
but when I try to add , count(*) after where content is, than while() loop echoes only one result, even when $title_arr[4](which stands for count) results in many.
Is it possible to do it this sort of way, or should I be running two separate queries?
You shouldn't do that in one query.
Think about the result you're expecting: when you do a count(*) query, what you get back is a result with only one row and one value. If you select multiple lines, then what should it do? Inject the count into each row of the data?
From a logical perspective, those are two different things you're looking for.
EDIT: counting the rows in your result after the fact is probably the best option, but that won't work if you're only looking for the first 10 entries, and there's no reason to SELECT the whole table if you don't need all the data. That's why count(*) is fulfilling such a different role.
COUNT() is an aggregate function so you can't use it like this. But if all you want is the number of rows this query would have returned you can use SQL_CALC_FOUND_ROWS to get the number of rows that would have been returned if thee was no LIMIT clause. You then can get the results by calling SELECT FOUND_ROWS() after your query is run.

Order By DESC/ASC not working within PHP Query

I have this code so far which is within 2 while loops:
mysql_query("SELECT * FROM listing WHERE
(category_id='$category' OR category_id_2='$category' OR category_id_3='$category')
AND listing_status='1' AND listing_type='1' AND listing_id='$listing_id'
ORDER BY overall DESC");
The data is showing exactly what I want, however the ORDER BY simply isn't working. I'm not too sure what it's ordering by. The overall column itself is DECIMAL(12,2).
The values are saved to only 2 decimal places. For instance, in each row it could be 2.56, 2.89. In this case I want the 2.89 to show before the 2.56. However, it's not.
Many thanks in advance.
I believe you are only selecting one element at a time in your query, something like
while(...){
$category = ...;
$listing_id = ...;
// Your query which only returns one result here
}
Then since your query only returns one result it has nothing to sort, and you see the results in the order the queries are executed.
You need to rewrite your query to select all the rows you want in one go instead of having it in a loop if you want ORDER BY to work. Using IN in your query may help you.
Have you tried casting the field as a decimal in the order by?
ORDER BY CAST(overall as DECIMAL) DESC
I have managed to solve the problem.
By implementing the 'overall' column in the first loops table, instead of the second. It orders the data first by overall, and then goes ahead and gathers the other data from the second table.
Many thanks for your help.
Try:
mysql_query("SELECT * FROM listing WHERE
(category_id='$category' OR category_id_2='$category' OR category_id_3='$category')
AND listing_status='1' AND listing_type='1' AND listing_id='$listing_id'
ORDER BY overall+0 DESC");
The query is fine. The problem is probably with how you iterate returned data. Try changing it.
If not, provide us with the whole relevant piece of your PHP code.
I don't know why, but I found out by copying and pasting from phpmyadmin that this worked to solve a similar problem. The ' is changed to ` - dunno if it's important. But definitely ASC worked with the second way.
Important - the have been stripped from the second method, put them around the table name and the column names.
instead of
$sql = "SELECT * FROM 'dczcats' ORDER BY 'first' , 'second' ASC";
I typed this
$sql = "SELECT * FROM `dczcats` ORDER BY `dczcats`.`first` , `dczcats`.`second` ASC";

Categories