Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Having on columns not in SELECT

I have a table with 3 columns:

userid   mac_address   count

The entries for one user could look like this:

57193   001122334455   42
57193   000C6ED211E6   15
57193   FFFFFFFFFFFF   2

I want to create a view that displays only those MAC's that are considered "commonly used" for this user. For example, I want to filter out the MAC's that are used <10% compared to the most used MAC-address for that user. Furthermore I want 1 row per user. This could easily be achieved with a GROUP BY, HAVING & GROUP_CONCAT:

SELECT userid, GROUP_CONCAT(mac_address SEPARATOR ',') AS macs, count
FROM mactable
GROUP BY userid
HAVING count*10 >= MAX(count)

And indeed, the result is as follows:

57193   001122334455,000C6ED211E6   42

However I really don't want the count-column in my view. But if I take it out of the SELECT statement, I get the following error:

#1054 - Unknown column 'count' in 'having clause'

Is there any way I can perform this operation without being forced to have a nasty count-column in my view? I know I can probably do it using inner queries, but I would like to avoid doing that for performance reasons.

Your help is very much appreciated!

like image 569
Rapsey Avatar asked Jul 14 '11 11:07

Rapsey


People also ask

Is it possible to order columns that are not in select list?

Bookmark this question. Show activity on this post. In theory, every statement in SQL Server create virtual table passed to next statement. In other words, when FROM and Where clause are finished, next step is SELECt columns from virtual group created step before. But, it is possible to order result set by column that is not listed in select list.

Which clause is allowed over column that is not in select list?

ORDER BY clause is allowed over column that is not in SELECT list? Bookmark this question. Show activity on this post. In theory, every statement in SQL Server create virtual table passed to next statement. In other words, when FROM and Where clause are finished, next step is SELECt columns from virtual group created step before.

How do I use the not in operator in SQL SELECT?

This SQL SELECT example introduces putting the NOT IN operator in a HAVING clause and uses the != operator instead of <> -- both of which work exactly the same way as the prior IF, WHERE, and <> examples. Since the result of the COUNT function is a number there are no quotes in the value list.

How to use the HAVING clause in the SELECT statement?

The HAVING clause is often used with the GROUP BY clause in the SELECT statement. If you use a HAVING clause without a GROUP BY clause, the HAVING clause behaves like the WHERE clause. The following illustrates the syntax of the HAVING clause:


1 Answers

As HAVING explicitly refers to the column names in the select list, it is not possible what you want.
However, you can use your select as a subselect to a select that returns only the rows you want to have.

SELECT a.userid, a.macs
FROM
(
    SELECT userid, GROUP_CONCAT(mac_address SEPARATOR ',') AS macs, count
    FROM mactable
    GROUP BY userid
    HAVING count*10 >= MAX(count)
) as a

UPDATE:
Because of a limitation of MySQL this is not possible, although it works in other DBMS like Oracle. One solution would be to create a view for the subquery. Another solution seems cleaner:

CREATE VIEW YOUR_VIEW (userid, macs) AS
SELECT userid, GROUP_CONCAT(mac_address SEPARATOR ',') AS macs, count
FROM mactable
GROUP BY userid
HAVING count*10 >= MAX(count)

This will declare the view as returning only the columns userid and macs although the underlying SELECT statement returns more columns than those two.
Although I am not sure, whether the non-DBMS MySQL supports this or not...

like image 161
Daniel Hilgarth Avatar answered Oct 30 '22 03:10

Daniel Hilgarth