Фильтрация запросов - PullRequest
       5

Фильтрация запросов

1 голос
/ 04 ноября 2011

Я не думаю, что это возможно, но я хотел убедиться.

Допустим, я хотел получить средний возраст пользователей, предполагающих некоторые условия.

SELECT avg(age) as avg_a FROM users where something something;

Теперьскажем, клиент хочет получить средний возраст, средний возраст для мужчин и средний возраст для женщин.

что-то вроде

SELECT avg(age) as avg_a, avg(age where female) avg_f, avg(age where male) avg_m FROM users where something something;

Возможно ли что-то подобное или даже мудро?

Как бы я поступил так?Или я должен просто выполнить 3 запроса каждый раз?

Ответы [ 3 ]

2 голосов
/ 04 ноября 2011

Да, вы можете использовать оператор case в своей функции агрегирования. См:

SELECT
    avg(age) avg_age,
    avg(case when gender = 'M' then age end) male_avg_age,
    avg(case when gender = 'F' then age end) female_avg_age
FROM users;
0 голосов
/ 04 ноября 2011

Чтобы получить среднее для каждого пола и среднее для всех, вам нужно будет использовать предложение WITH ROLLUP в GROUP BY.

Например, вот несколько примеров данных:

use junk
DROP TABLE IF EXISTS people;
CREATE TABLE people
(name VARCHAR(20),age INT,gender CHAR(1));
INSERT INTO people VALUES
('rolando'  ,46,'M'),
('pamela'   ,40,'F'),
('carlik'   ,23,'M'),
('javonne'  ,22,'M'),
('dominique',15,'F'),
('diamond'  ,13,'F');
SELECT * FROM people;

Это запрос, который вам нужен:

SELECT IFNULL(gender,'ALL') gender,AVG(age) average_age
FROM people GROUP BY gender WITH ROLLUP;

Вот вывод:

mysql> CREATE TABLE people
    -> (name VARCHAR(20),age INT,gender CHAR(1));
Query OK, 0 rows affected (0.08 sec)

mysql> INSERT INTO people VALUES
    -> ('rolando'  ,46,'M'),('pamela'   ,40,'F'),
    -> ('carlik'   ,23,'M'),('javonne'  ,22,'M'),
    -> ('dominique',15,'F'),('diamond'  ,13,'F');
Query OK, 6 rows affected (0.06 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM people;
+-----------+------+--------+
| name      | age  | gender |
+-----------+------+--------+
| rolando   |   46 | M      |
| pamela    |   40 | F      |
| carlik    |   23 | M      |
| javonne   |   22 | M      |
| dominique |   15 | F      |
| diamond   |   13 | F      |
+-----------+------+--------+
6 rows in set (0.00 sec)

mysql> SELECT IFNULL(gender,'ALL') gender,AVG(age) average_age
    -> FROM people GROUP BY gender WITH ROLLUP;
+--------+-------------+
| gender | average_age |
+--------+-------------+
| F      |     22.6667 |
| M      |     30.3333 |
| ALL    |     26.5000 |
+--------+-------------+
3 rows in set, 1 warning (0.00 sec)

Другой стиль запроса был бы:

SELECT A.avgage avg_a,F.avgage avg_f,M.avgage avg_m FROM
(SELECT AVG(age) avgage FROM people) A,
(SELECT AVG(age) avgage FROM people WHERE gender='F') F,
(SELECT AVG(age) avgage FROM people WHERE gender='M') M;

Вот что получилось:

mysql> SELECT A.avgage avg_a,F.avgage avg_f,M.avgage avg_m FROM
    -> (SELECT AVG(age) avgage FROM people) A,
    -> (SELECT AVG(age) avgage FROM people WHERE gender='F') F,
    -> (SELECT AVG(age) avgage FROM people WHERE gender='M') M;
+---------+---------+---------+
| avg_a   | avg_f   | avg_m   |
+---------+---------+---------+
| 26.5000 | 22.6667 | 30.3333 |
+---------+---------+---------+
1 row in set (0.00 sec)

Попробуйте! !!! 1018 *

0 голосов
/ 04 ноября 2011
SELECT 
  avg(age) as avg_a, 
  avg(select age from users where female) avg_f, 
  avg(select age from users where male) avg_m 
FROM users 
WHERE something something;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...