问题
I am writing a SQL command to find majority of value(a value is returned as majority if its occurence in the table is more then 50%) in a table. For e.g. a Emp(name, age, dept) with values in table: (32, 33, 45, 45 ,45 21, 45)
So if user wants to get majority value of field age, he will run the command:
SELECT majority(age) FROM Emp
Now at the backend the corresponding SQL command generated will be like:
SELECT age FROM Emp GROUP BY age HAVING COUNT(*) > ((SELECT COUNT(*) FROM Emp) / 2);
This query returns 45 as result.
But for a user query like:
SELECT majority(age), dept FROM Emp GROUP BY dept
Then I am not sure how to create similar query with group by
feature, or should I create some other query? Thanks in advance
回答1:
(Assuming you are using Oracle - because in MySQL you can't write your own aggregates anyway)
I think you can do this with window functions:
This is the equivalent to the first example:
select distinct age
from (
select age,
dept,
count(*) over () as total_count,
count(*) over (partition by age) as age_count
from emp
)
where age_count >= total_count / 2;
By simply adding the department to the partition (group) definition this should give you what you want:
select distinct age
from (
select age,
dept,
count(*) over (partition by dept) as dept_count,
count(*) over (partition by dept, age) as age_count
from emp
)
where age_count >= dept_count / 2;
回答2:
What you are asking to perform is termed creating a user-defined aggregate function. This is a not a trivial task, but here is a tutuorial for doing so in Oracle.
User-defined aggregate functions in oracle 9i
来源:https://stackoverflow.com/questions/22533290/majority-function-in-sql