So we are doing some traffic reporting in our department.
Therefore we got a table named traffic_report, which is build up like
╔════════════════╦═══════════╦═════════════════════╦═════════════╦═════════════╗
║ hostname ║ interface ║ date_gmt ║ intraf_mpbs ║ outraf_mbps ║
╠════════════════╬═══════════╬═════════════════════╬═════════════╬═════════════╣
║ my-machine.com ║ NIC-5 ║ 2013-09-18 09:55:00 ║ 32 ║ 22 ║
║ my-machine.com ║ NIC-5 ║ 2013-09-17 08:25:00 ║ 55 ║ 72 ║
║ my-machine.com ║ NIC-5 ║ 2013-09-16 05:12:00 ║ 65 ║ 2 ║
║ my-machine.com ║ NIC-5 ║ 2013-09-15 04:46:00 ║ 43 ║ 5 ║
║ my-machine.com ║ NIC-5 ║ 2013-09-14 12:02:00 ║ 22 ║ 21 ║
║ my-machine.com ║ NIC-5 ║ 2013-09-13 22:13:00 ║ 66 ║ 64 ║
╚════════════════╩═══════════╩═════════════════════╩═════════════╩═════════════╝
I'd like to fetch the maximum of the traffic in and traffic out at the occured date.
My approach doing so is like this
SELECT hostname, interface, date_gmt, max(intraf_mbps) as max_in, max(outtraf_mbps) as max_out
FROM traffic_report
GROUP by hostname, interface
The approach produces a table like this
╔════════════════╦════════════╦═════════════════════╦════════╦═════════╗
║ hostname ║ interface ║ date_gmt ║ max_in ║ max_out ║
╠════════════════╬════════════╬═════════════════════╬════════╬═════════╣
║ my-machine.com ║ NIC-5 ║ 2013-09-18 09:55:00 ║ 66 ║ 72 ║
╚════════════════╩════════════╩═════════════════════╩════════╩═════════╝
The problem is, the date_gmt displayed is just the date of the first record entered to the table.
How do I instruct SQL to display me the date_gmt at which the max(intraf_mbps) occured?
Your issue is with mysql hidden fields:
MySQL extends the use of GROUP BY so that the select list can refer to
nonaggregated columns not named in the GROUP BY clause. This means
that the preceding query is legal in MySQL. You can use this feature
to get better performance by avoiding unnecessary column sorting and
grouping. However, this is useful primarily when all values in each
nonaggregated column not named in the GROUP BY are the same for each
group.
Mysql has not rank features either analytic functions, to get your results, a readable approach but with very poor performance is:
SELECT hostname,
interface,
date_gmt,
intraf_mbps,
outtraf_mbps
FROM traffic_report T
where intraf_mbps + outtraf_mbps =
( select
max(intraf_mbps + outtraf_mbps)
FROM traffic_report T2
WHERE T2.hostname = T.hostname and
T2.interface = T.interface
GROUP by hostname, interface
)
Sure you can work for a solution with more index friendly approach or avoid correlated subquery.
Notice than I have added both rates, in and out. Adapt solution to your needs.
Either of these approaches should work:
This first query returns the rows that match the maximum out and in values, so multiple rows can be returned if many records share the max or min values.
SELECT * from traffic_report
WHERE intraf_mpbs = (SELECT MAX(intraf_mpbs) FROM traffic_report)
or outraf_mpbs = (SELECT MAX(outraf_mpbs) FROM traffic_report)
This second query returns more of a MI style result, add other fields if you require them.
SELECT "MAX IN TRAFFIC" AS stat_label,date_gmt AS stat_date, traffic_report.intraf_mpbs
FROM traffic_report,(select MAX(intraf_mpbs) AS max_traf FROM traffic_report) as max_in
WHERE traffic_report.intraf_mpbs = max_in.max_traf
UNION
SELECT "MAX OUT TRAFFIC" AS stat_label,date_gmt AS stat_date, traffic_report.outraf_mpbs
FROM traffic_report,(SELECT MAX(outraf_mpbs) AS max_traf FROM traffic_report) AS max_out
WHERE traffic_report.outraf_mpbs = max_out.max_traf
Hope this helps.
Related
The title may be confusing, but so is the solution I am trying to SELECT from a table of 173k words a distinct word list by letter.
I already tried selecting distinct letters, running on a mariadb 10.1.37
SELECT DISTINCT LEFT(word, 1)
For example a SELECT shouldnt contain more than 1 word beginning with an "A".
Example Table (Because it's hard to understand)
╔═══════════╦═════════╗
║ Word ║ Result ║
╠═══════════╣ ---- ║
║ Charlie ║ Ava ║
╠═══════════╣ Bianca ║
║ Caddie ║ Charlie ║
╠═══════════╣ ║
║ Brooklynn ║ ║
╠═══════════╣ ║
║ Ava ║ ║
╠═══════════╣ ║
║ Alexander ║ ║
╠═══════════╣ ║
║ Bianca ║ ║
╚═══════════╩═════════╝
You can use the following solution using a GROUP BY on the first character:
SELECT MIN(word) FROM table_name GROUP BY LEFT(word, 1)
You can use MIN or MAX to get the first or last word on every group.
demo un dbfiddle.uk
I have a table with column containing many URLs, I want to get all the distinct hostnames with their count
column_links
----------
http://abcd.com/efgh/ijk/lmn
http://qwer.com/qwqwq/qwq/wdsd
http://abcd.com/jhksdh/khsdh/khd
http://abcd.com/dsfsdh/khsdh/dsfsdf
http://qwer.com/ihwlidhw/ddsd/wqeqe
should produce
╔════╦══════════════════╦══════╗
║ ║ hostnames ║ 2 ║
╠════╬══════════════════╬══════╣
║ 1 ║ http://abcd.com ║ 3 ║
║ 2 ║ http://qwer.com ║ 2 ║
╚════╩══════════════════╩══════╝
I can't make up a query, i am not good at regex
SUBSTRING_INDEX() is a string function that does what you need to do in editing URLs into hostnames. This query should do the trick for you. (http://sqlfiddle.com/#!9/940481/1/0)
SELECT SUBSTRING_INDEX(column_links,'/',3) host,
COUNT(*) number
FROM links
GROUP BY SUBSTRING_INDEX(column_links,'/',3)
Okay so basically I am trying to run a simple query with a subquery on phpmyadmin using mysql and it won't stop loading after I run it. The query is:
SELECT t.tagValue FROM tags t WHERE t.tagID IN (SELECT ua.tagID FROM user_taggedArtists ua WHERE ua.userID = 2);
I have ran the individual queries on their own without combining them together and they seem to do what I want, but when I mix them into a subquery form phpmyadmin just loads forever, like I am getting an infinite loop or something.
tags table looks like that:
╔═══════╦═════════════╗
║ tagID ║ tagValue ║
╠═══════╬═════════════╣
║ 1 ║ metal ║
║ 2 ║ alternative ║
║ 3 ║ pop ║
╚═══════╩═════════════╝
etc.
user_taggedArtists table looks like this:
╔════════╦══════════╦═══════╦═════╦═══════╦═══════╗
║ userID ║ artistID ║ tagID ║ day ║ month ║ year ║
╠════════╬══════════╬═══════╬═════╬═══════╬═══════╣
║ 2 ║ 52 ║ 1 ║ 1 ║ 4 ║ 2009 ║
║ 2 ║ 52 ║ 1 ║ 1 ║ 4 ║ 2009 ║
║ 2 ║ 52 ║ 1 ║ 1 ║ 4 ║ 2009 ║
╚════════╩══════════╩═══════╩═════╩═══════╩═══════╝
ect.
Not sure what I am doing wrong here and any help would be greatly appreciated.
Thank you!
Hard to say 'zatly, but "IN", generally, is slow. Try a JOIN and WHERE. I'm going to pretend we can join on tagID. You should have indexes on the join column(s). If not anything you do will perform poorly.
SELECT t.tagValue
FROM tags t
INNER JOIN user_taggedArtists ua ON
t.tagID = ua.tagID
WHERE ua.userID = 2
I have a table that has four columns: id, item_number, feature, value.
The table looks like this and has about 5 million entries.
╔════╦═════════════╦═════════╦═══════╗
║ id ║ item_number ║ feature ║ value ║
╠════╬═════════════╬═════════╬═══════╣
║ 1 ║ 234 ║ 5 ║ 15 ║
║ 2 ║ 234 ║ 3 ║ 256 ║
║ 3 ║ 453 ║ 5 ║ 14 ║
║ 4 ║ 453 ║ 4 ║ 12 ║
║ 5 ║ 453 ║ 7 ║ 332 ║
║ 6 ║ 17 ║ 5 ║ 88 ║
║ 7 ║ 17 ║ 9 ║ 13.86 ║
╚════╩═════════════╩═════════╩═══════╝
How can I sort the table so that I can get the item_numbers in descending order based on the feature value?
I am also selecting other feature numbers with their values but I only want to sort by feature number 5.
You need to do order by first with feature and then with item_numbers
select * from `table` order by `feature`, `item_numbers` desc
Using order by with desc and where clauses:
select `item_numbers`
from `tbl`
where `feature` = 5
order by `value` desc
In your query, add
order by item_number desc
If you are trying to query based on a specific feature, so only receive one set of data for a feature at at time, add
where feature = 'feature'
where "feature" is the feature value you want to search for. If you are looking to provide all features but sort them, you can add
order by feature, item_number desc
and you will be give all features in ascending order and together (grouped) then the items_number(s) in descending order
EDIT::
Sounds like from your latest comment, this may be your solution:
SELECT item_number FROM table WHERE feature = '5' ORDER BY value DESC
My table has a list of users with Items associated to them. I hope to be able to consolidate the items field into a list or create another column if the row has a matching User/email.
I have the following structure with in the MySQL table:
╔═══════════╦═════════════╦═════════════╦═════════════╦═════════════╦════════════╗
║ ID ║ User_ID ║ Item ║ Date ║ User ║ Email ║
╠═══════════╬═════════════╬═════════════╬═════════════╬═════════════╬════════════╣
║ 1 ║ 1 ║ Laptop 1 ║ 30th Nov ║ John ║ J#test.com ║
║ 2 ║ 2 ║ Laptop 3 ║ 12th Nov ║ Emma ║ e#test.com ║
║ 3 ║ 2 ║ Camera 3 ║ 12th Nov ║ Emma ║ e#test.com ║
╚═══════════╩═════════════╩═════════════╩═════════════╩═════════════╩════════════╝
I am very new to SQL but i think i would need to use some type of transpose field to a column function?
Any help will be greatly appreciated
Thanks
I think you want group_concat(). Personally, I would use user_id, rather than user/email. or, perhaps all three together. Something like this:
select user_id, user, email, group_concat(item) as items
from table t
group by user_id, user, email;