процент покрытия с помощью сложного SQL-запроса ...? - PullRequest
4 голосов
/ 23 февраля 2009

Хорошо, я пытаюсь решить эту проблему около 2 часов ... Пожалуйста, сообщите:

Таблица:

PROFILE [id (int), name (varchar), ...]
SKILL   [id (int), id_profile (int), id_app (int), lvl (int), ...]
APP     [id (int), ...]

Уровень в основном может быть от 0 до 3.

Я пытаюсь получить этот конкретный показатель: «Какой процент приложений покрывают как минимум два человека с навыком 2 или выше?»

Большое спасибо

Ответы [ 5 ]

4 голосов
/ 23 февраля 2009
SELECT AVG(covered)
FROM (
  SELECT CASE WHEN COUNT(*) >= 2 THEN 1 ELSE 0 END AS covered
  FROM app a
  LEFT JOIN skill s ON (s.id_app = a.id AND s.lvl >= 2)
  GROUP BY a.id
)

Более эффективный способ для MySQL:

SELECT AVG
       (
         IFNULL
         (
           (
           SELECT 1
           FROM skill s
           WHERE s.id_app = a.id
           AND s.lvl >= 2
           LIMIT 1, 1
           ), 0
         )
       )
FROM app a

Счет прекращается, как только он находит второго умелого person для каждого app.

Эффективно, если у вас есть несколько app, но много person.

0 голосов
/ 23 февраля 2009

Логика: процент = 100 * (количество интересующих приложений) / (общее количество приложений)

select 'percentage' = 
-- 100 times
  ( cast( 100 as float ) * 
-- number of apps of interest
  ( select count(id_app) 
    from ( select id_app, count(*) as skilled_count
           from skill
           where lvl >= 2
           group by id_app 
           having count(*) >= 2 ) app_counts ) 
-- divided by total number of apps
  / ( select count(*) from app ) 

Требуется преобразование в число с плавающей точкой, поэтому sql не просто выполняет целочисленную арифметику.

0 голосов
/ 23 февраля 2009

Непроверенные

select convert(float,count(*)) / (select count(*) from app) as percentage
from (
    select count(*) as number
    from skill
    where lvl >= 2
    group by id_app ) t
where t.number >= 2
0 голосов
/ 23 февраля 2009

Я не уверен, что это лучше или хуже, чем ответ Тванфоссона, но здесь все равно:

SELECT convert(float, count(*)) / (Select COUNT(id) FROM APP) AS percentage
FROM APP INNER JOIN SKILL ON APP.id = SKILL.id 
WHERE (
   SELECT COUNT(id) 
   FROM SKILL AS Skill2 WHERE Skill2.id_app = APP.id and lvl >= 2
) >= 2
0 голосов
/ 23 февраля 2009
SELECT SUM( CASE lvl WHEN 3 THEN 1 WHEN 2 THEN 1 ELSE 0 END ) / SUM(1) FROM SKILL

Если в вашей базе данных есть функция if / then вместо CASE, используйте это. Например, в MySQL:

SELECT SUM( IF( lvl >= 2, 1, 0 ) ) / SUM(1) FROM SKILL
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...