get mysql results by highest count - mysql

I have a table with fields:
id, albumid, userid, keywords where keywords is varchar and can be more than one by delimteter eg : one,two,three
I want to get the top 10 results of the most popular keyword but not by the same user
I currently use this but not sure if its correct:
$tableName = $db->nameQuote('#__mytable');
$sql = "SELECT `id`,`albumid`,`userid`,`keywords`, COUNT(keywords) AS popular FROM ".$tableName." GROUP BY `userid` HAVING COUNT(*) > 1 ORDER BY popular DESC LIMIT ".$lim0.",".$lim;
$db->setQuery($sql);
Is the following code correct. Im not sure if im getting the keyword with most duplicate entries...

Try this query on for size, I just fudged around your groupings, and using DISTINCT userid as the counting metric
"SELECT `id`,`albumid`,`keywords`, COUNT(DISTINCT userid) AS popularity FROM ".$tableName." GROUP BY `keywords` HAVING popularity >= 1 ORDER BY popularity DESC LIMIT ".$lim0.",".$lim;
However, if your keywords column is comma delimited, this query will NOT work. This query operates on the fact that each record has a single keyword entry

Related

In PhpMyadmin Count rows issue with mysql

I added below query in phpmyadmin
SELECT id,u_id,count(u_id) As cnt
FROM `pager`
WHERE type = 'profile' group by u_id
Query Executed.
I got below output showing (0- 30 results) total 24000 records found
I tried same query in different format
SELECT count(u_id) As cnt,id,u_id
FROM `pager`
WHERE type = 'profile' group by u_id
Query Executed.
I got below Query Executed Successfully.SHowing just 30 records , No Pagination dropdown.I can't click id and u_id field heading to sort..Someone please help what is the issue..I think both query should execute 24000 records..Please advise
PhpMyAdmin display default results as per it's settings which you can change from Number of rows : dropdown value in the interface.
If you need to display all your result, then you must add limit clause in your query to display all records
SELECT id,u_id,count(u_id) As cnt
FROM `pager`
WHERE type = 'profile' group by u_id
LIMIT 0, 999999
Otherwise, it will display 30 resuts (or whatever default PhpMyAdmin settings)
NOTE: To sort out the results, add Order by clause in your query then the query would look like following:
SELECT id,u_id,count(u_id) As cnt
FROM `pager`
WHERE type = 'profile' group by u_id
ORDER BY `id` DESC
LIMIT 0, 999999
Hope, it helps you.

SQL: How to decrease the statement execution time?

I'm not an expert in SQL, i have an sql statement :
SELECT * FROM articles WHERE article_id IN
(SELECT distinct(content_id) FROM contents_by_cats WHERE cat_id='$cat')
AND permission='true' AND date <= '$now_date_time' ORDER BY date DESC;
Table contents_by_cats has 11000 rows.
Table articles has 2700 rows.
Variables $now_date_time and $cat are php variables.
This query takes about 10 seconds to return the values (i think because it has nested SELECT statements) , and 10 seconds is a big amount of time.
How can i achieve this in another way ? (Views or JOIN) ?
I think JOIN will help me here but i don't know how to use it properly for the SQL statement that i mentioned.
Thanks in advance.
A JOIN is exactly what you are looking for. Try something like this:
SELECT DISTINCT articles.*
FROM articles
JOIN contents_by_cats ON articles.article_id = contents_by_cats.content_id
WHERE contents_by_cats.cat_id='$cat'
AND articles.permission='true'
AND articles.date <= '$now_date_time'
ORDER BY date DESC;
If your query is still not as fast as you would like then check that you have an index on articles.article_id and contents_by_cats.content_id and contents_by_cats.cat_id. Depending on the data you may want an index on articles.date as well.
Do note that if the $cat and $now_date_time values are coming from a user then you should really be preparing and binding the query rather than just dumping these values into the query.
This is the query we are starting with:
SELECT a.*
FROM articles a
WHERE article_id IN (SELECT distinct(content_id)
FROM contents_by_cats
WHERE cat_id ='$cat'
) AND
permission ='true' AND
date <= '$now_date_time'
ORDER BY date DESC;
Two things will help this query. The first is to rewrite it using exists rather than in and to simplify the subquery:
SELECT a.*
FROM articles a
WHERE EXISTS (SELECT 1
FROM contents_by_cats cbc
WHERE cbc.content_id = a.article_id and cat_id = '$cat'
) AND
permission ='true' AND
date <= '$now_date_time'
ORDER BY date DESC;
Second, you want indexes on both articles and contents_by_cats:
create index idx_articles_3 on articles(permission, date, article_id);
create index idx_contents_by_cats_2 on contents_by_cat(content_id, cat_id);
By the way, instead of $now_date_time, you can just use the now() function in MySQL.

how to retrieve two records in a table for each record in mysql

I have a "reply" table with structure.
replyno topicno replydesc replyrank
Now i need to retrieve top 2 records ordered by replyrank in descending order (means first 2 high ranked records) for each topicno (which is a foreign key).
I need a query in mysql that can extract result set like this for all topic numbers.
please give me optimized query that can execute faster
Try this:
SELECT replyno, topicno, replydesc, replyrank
FROM (SELECT replyno, topicno, replydesc, replyrank,
IF(#topicno = #topicno:=topicno, #id:=#id+1, #id:=1) AS id
FROM reply, (SELECT #id:=1, #topicno:=0) A
ORDER BY topicno, replyrank DESC
) AS A
WHERE id <= 2;
Try this Query i think it gonna work for you
SELECT replyno, topicno FROM reply ORDER BY replyrank DESC LIMIT 2

mysql search in main query and subquery

Having the following query where i am trying to search in a query, i might be writing a wrong syntax, but i am not sure how to correct it. I want to search for the text in the main table and the subquery table too.
here is my query
select mytable.*
from mytable
where spam = 0
and deleted = 0
and draft = 0
and (subject like '%guss%' or body like '%guss%' or
(select CONCAT(users.firstname,' ', users.lastname) as fname,users.email
from users where firstname like '%guss%' or lastname like 'guss'))
and id = 24
order by id desc
getting this Error
[Err] 1241 - Operand should contain 1 column(s)
Update #1
select mytable.*
from mytable
where spam = 0
and deleted = 0
and draft = 0
and (subject like '%eli%' or body like '%eli%' or
(select users.firstname
from users where firstname like '%eli%') or
(select users.lastname
from users where lastname like '%eli%'))
and id_receiver = 24
order by id desc
Here the error:
(select CONCAT(users.firstname,' ', users.lastname) as fname,users.email
from users where firstname like '%guss%' or lastname like 'guss'))
In your subquery you can return only one column
This is the first column: CONCAT(users.firstname,' ', users.lastname) as fname
This is the second column: users.email
You put a 2-column result as an operand of OR expression.
This causes the issue. It should return one column or be compared to something.
But if you want to search in both tables I guess UNION would be something you need.
Though I think this is wrong I don't believe mytable.id relates to users.id but that's what a comment said...
SELECT Distinct mytable.*
FROM mytable
INNER JOIN users
on myTable.ID = users.Id
WHERE mytable.spam = 0
and mytable.deleted = 0
and mytable.draft = 0
and CONCAT_WS(mytable.subject, mytable.body, users.firstname, users.lastname) like '%eli%'
and mytable.id_receiver = 24
ORDER BY mytable.id desc
I removed the or using string concatenation. We want any record having the text of 'eli' in any of the columns subject, body, firstname, lastname. The system would have to loop through each column checking for a %eli% value. In theory up to 4 loops. By adding all the columns together to form one string and checking for eli we eliminate extra looping the engine would have to do at an overhead of the string concatenation. This should be faster.
I used distinct as I don't know what results you want and if the join will result in multiple records that serve no purpose. Since a * is being used I couldn't use a group by properly.
I joined to users assuming that you only want records in mytable that link to a user. This may be a wrong assumption.

mysql: SELECT WHERE id IN() and others

I'm using this query to select a set of records from a MySQL database:
SELECT *
FROM table
WHERE id IN(10,14,12,11,8,7,4)
AND actief='on'
ORDER BY FIELD(id,10,14,12,11,8,7,4)
This will give me the given ID's. In this case I will get a maximum of 7 records. But it can be less if for example ID '14' has active='off'.
But what I need is a set of 20 records where het list IN(10,14,12,11,8,7,4) must be in the result if they also meet the condition active='on'. If this returns 6 records, then I want the query to select another 14 records. Selecting highest ID first, must meet active='on' and may not already be in the result.
Can this be achieved by one SQL statement. Or should I first put the result of the mentionend query in an array and in a second array select the remaining records. And finaly put those also in the array?
You want to sort rather than filter the results. I think this is the query you want:
SELECT *
FROM table
ORDER BY (id IN(10,14,12,11,8,7,4) AND actief = 'on') desc,
FIELD(id,10,14,12,11,8,7,4),
id desc
LIMIT 20;
EDIT:
The final solution only wanted actief = 'on', so:
SELECT *
FROM table
WHERE actief = 'on'
ORDER BY (id IN (10,14,12,11,8,7,4)) desc,
FIELD(id,10,14,12,11,8,7,4),
id desc
LIMIT 20;