SQL: возникли проблемы с запросом, который получает проценты с использованием агрегатных функций - PullRequest
0 голосов
/ 12 августа 2010

Я ни в коем случае не являюсь экспертом в SQL, и мне трудно получать нужные мне данные из запроса. Я работаю с одной таблицей Journal_Entry, которая имеет несколько столбцов. Один столбец - это Status_ID, который является внешним ключом таблицы состояния с тремя значениями: «Зеленый», «Желтый» и «Красный». Кроме того, запись журнала регистрируется для определенного пользователя (идентификатор_пользователя).

Я пытаюсь получить количество записей журнала, зарегистрированных для каждого статуса, в процентах от общего количества записей журнала, зарегистрированных конкретным пользователем. До сих пор у меня есть следующее для статуса 1, который зеленый (и я знаю, что это не работает):

SELECT  CAST((SELECT COUNT(Journal_Entry_ID) 
        FROM Journal_Entry 
        WHERE Status_ID = 1 AND User_ID = 3 / 
        SELECT COUNT(Journal_Entry_ID) 
        FROM Journal_Entry AND User_ID = 3)) AS FLOAT * 100

Мне нужно продолжить запрос для двух других идентификаторов состояния, 2 и 3, и в идеале хотелось бы завершить выбор трех столбцов в процентах, по одному для каждого состояния: «Green_Percent», «Yellow_Percent» и « Red_Percent».

Это, наверное, самый разрозненный вопрос, который я когда-либо задавал, поэтому я прошу прощения за отсутствие ясности. Я буду рад уточнить при необходимости. Также я использую SQL Server 2005.

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

Ответы [ 3 ]

2 голосов
/ 12 августа 2010

Использование:

  SELECT je.statusid,
         COUNT(*) AS num,
         (COUNT(*) / (SELECT COUNT(*)+.0
                       FROM JOURNAL_ENTRY) ) * 100
    FROM JOURNAL_ENTRY je
GROUP BY je.statusid

Тогда нужно отформатировать необходимую точность:

CAST(((COUNT(*) / (SELECT COUNT(*)+.0 FROM BCCAMPUS.dbo.COURSES_RFIP)) * 100)
     AS DECIMAL(4,2))

... даст два десятичных знака.Приведите результат к INT, если вам не нужны десятичные знаки.

Вы можете использовать CTE, чтобы минимизировать дублирование:

WITH cte AS (
   SELECT je.*
     FROM JOURNAL_ENTRY je
    WHERE je.user_id = 3)
  SELECT c.statusid,
         COUNT(*) AS num,
         (COUNT(*) / (SELECT COUNT(*)+.0
                       FROM cte) ) * 100
    FROM cte c
GROUP BY c.statusid
0 голосов
/ 12 августа 2010

Это должно работать:

SELECT
    user_id,
    (CAST(SUM(CASE WHEN status_id = 1 THEN 1 ELSE 0 END) AS DECIMAL(6, 4))/COUNT(*)) * 100 AS pct_green,
    (CAST(SUM(CASE WHEN status_id = 2 THEN 1 ELSE 0 END) AS DECIMAL(6, 4))/COUNT(*)) * 100 AS pct_yellow,
    (CAST(SUM(CASE WHEN status_id = 3 THEN 1 ELSE 0 END) AS DECIMAL(6, 4))/COUNT(*)) * 100 AS pct_red
FROM
    Journal_Entry
WHERE
    user_id = 1
GROUP BY
    user_id

Если вам не нужен возвращенный user_id, вы можете избавиться от этого и предложения GROUP BY, если только вы возвращаете данные только для одного пользователя (или вы хотите, чтобы агрегаты для всех пользователей были указаны в предложении WHERE ). Если вы хотите его для каждого пользователя, вы можете оставить GROUP BY и просто избавиться от предложения WHERE.

0 голосов
/ 12 августа 2010
DECLARE @JournalEntry TABLE
(   StatusID        INT
);
INSERT INTO @JournalEntry (StatusID) VALUES
    (1), (1),(1),(1),(1),(1),(1)
   ,(2), (2),(2),(2),(2),(2),(2)
   ,(3), (3),(3),(3),(3),(3),(3);

 SELECT 
 CAST(SUM(CASE WHEN StatusID = 1 THEN 1 ELSE 0 END) AS DECIMAL) / CAST(COUNT(*) AS DECIMAL) Green
,CAST(SUM(CASE WHEN StatusID = 2 THEN 1 ELSE 0 END) AS DECIMAL) / CAST(COUNT(*) AS DECIMAL) Yellow
,CAST(SUM(CASE WHEN StatusID = 3 THEN 1 ELSE 0 END) AS DECIMAL) / CAST(COUNT(*) AS DECIMAL) Blue
 FROM @JournalEntry;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...