Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

How to use MySQL to Limit secondary results

Posted on 2011-03-10
11
528 Views
Last Modified: 2012-05-11
I've been thinking on this one and it's stumped me.  

I need to query a user table (dhcpclients) for all users (31 records) and include 25 rows for each user from another table (logs). So the end result is 775 rows- 25 for each 31. Make sense?

Attached is the code I'm working with.  

The query that makes up the "join" in there works fine but obviously stops at the limit- which is this case would be one user record with 25 of the log table records. the problem is if I move the limit up it's not going to move to the next user until it's exhausted all the matches in the log table. I need it to quit after 25 and move to the next user.

Make sense?


SELECT dhcp.machinename, log1.* FROM dhcpclients dhcp
JOIN (
SELECT DATE(logs.date) AS 'Date', SUBSTRING_INDEX(SUBSTRING_INDEX(logs.request,'://',-1),'/',1) AS 'Site',
COUNT(logs.request) AS 'Hits',
FORMAT(SUM(logs.elapsed)/1000,2) AS 'Xfr Time(sec)', FORMAT(SUM(logs.bytes)/1024,2) AS 'KB Txfrd',
FORMAT((((SUM(logs.bytes)/1024)/1024)*8)/(SUM(logs.elapsed)/1000),2) AS 'Mbits/s', logs.ip
FROM logs 
WHERE logs.request NOT LIKE '[%' AND SUBSTRING_INDEX(SUBSTRING_INDEX(logs.request,'://',-1),'/',1) NOT LIKE '%knothe.com%'
AND DATE(logs.date) = DATE(NOW())
GROUP BY DATE(logs.date),logs.ip, SUBSTRING_INDEX(SUBSTRING_INDEX(logs.request,'://',-1),'/',1)
ORDER BY DATE(logs.date) DESC, COUNT(logs.request)DESC, SUM(bytes)/1024 DESC
LIMIT 25 ) 

log1 ON log1.ip = dhcp.ipaddress 

ORDER BY dhcp.machinename ASC

Open in new window

0
Comment
Question by:digitalwav
  • 6
  • 3
  • 2
11 Comments
 
LVL 10

Expert Comment

by:APNFSSC
ID: 35101528
Does your logs table have a primary auto incrementing key?

In this thread a method is described but it looks to me that it requires the key to work.

http://forums.mysql.com/read.php?20,135077,135077#msg-135077

First post then result

http://forums.mysql.com/read.php?20,135077,135107#msg-135107

0
 
LVL 8

Expert Comment

by:raulggonzalez
ID: 35106525
Hi,

This works for MSSQL, but maybe you can make it work in MySQL ...

It's just an example with 2 tables, parent and child 1 to many.


Hope it helps
SELECT *  FROM 
	(SELECT RANK() OVER 
			(PARTITION BY Parent.ID ORDER BY Child.ID ASC) AS [RANK], Parent.ID, Child.ID as childID
		FROM XXXXX AS Parent
			INNER JOIN YYYYY AS Child
				ON Child.parentID = Parent.ID
	) AS TB
WHERE TB.[RANK] <= 25

Open in new window

0
 
LVL 1

Author Comment

by:digitalwav
ID: 35108107
Yes it has a auto increment key. I'll check out the thread you're referring to.
0
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

 
LVL 1

Author Comment

by:digitalwav
ID: 35131028
Ok, I tried the having count(xx.xx) idea and the results don't make any sense.  The rank idea doesn't work unless the rank can reset after each change in column 'machine name'

This simply may not be possible in pure sql. I may have to do it in php.
0
 
LVL 1

Author Comment

by:digitalwav
ID: 35131052
Let me try to explain this another way. I want the top 25 sites by machine_name. In this case the query I have gives ALL sites by machine_name for the day. If I just add limit to the statement it limits the overall results to 25, not the result by machine_name.
0
 
LVL 8

Expert Comment

by:raulggonzalez
ID: 35132497
the idea of RANK is exactly what you want, I tried in my MS SQL database and it will return exactly what you need.

SELECT RANK() OVER
                  (PARTITION BY Parent.ID ORDER BY Child.ID ASC)

Gives a rank for every parentID so you will have
 
Parent   Child
1             1
1             2
1             3
2             1
2             2

and so on...

however I don't know how you can 'translate' this into MySql ...

Cheers
0
 
LVL 8

Expert Comment

by:raulggonzalez
ID: 35132536
Sorry, the name of the columns is not right, It'll be like this

Parent   [RANK]
1             1
1             2
1             3
2             1
2             2
0
 
LVL 1

Author Comment

by:digitalwav
ID: 35136972
I'll see what I can come up with. MySQL can do something similar to Rank. I'll show my work when done.
0
 
LVL 1

Author Comment

by:digitalwav
ID: 35137465
The rank idea doesn't work. The only rank method for mysql is basically a counter 'column' which results in each record getting a consecutively higher number.  There is no way to reset that counter that I can see when then parent column changes to a new value.
0
 
LVL 10

Accepted Solution

by:
APNFSSC earned 500 total points
ID: 35142554
digitalwav I think what you are after is a store procedure, so that you can loop through the subnets.

http://www.mysqltutorial.org/mysql-stored-procedure-tutorial.aspx

0
 
LVL 1

Author Closing Comment

by:digitalwav
ID: 35148027
yup, APNFSSC, that's what I'm going to have to do. Thanks for the pointer. I was hoping to avoid procedures.
0

Featured Post

How our DevOps Teams Maximize Uptime

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us. Read the use case whitepaper.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
TSQL - How to declare table name 26 42
SQL Query assistance 16 36
MYSQL responding very slow 3 23
Update one table with results from another table in SQL 6 27
I'm trying, I really am. But I've seen so many wrong approaches involving date(time) boundaries I despair about my inability to explain it. I've seen quite a few recently that define a non-leap year as 364 days, or 366 days and the list goes on. …
Password hashing is better than message digests or encryption, and you should be using it instead of message digests or encryption.  Find out why and how in this article, which supplements the original article on PHP Client Registration, Login, Logo…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

838 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question