Вы можете попробовать посмотреть альфа-фигуры. Библиотека CGAL может их вычислить.
Изменить: я вижу, что в документе, который вы связали, используются альфа-формы, а также есть список алгоритмов. Разве это недостаточно высокий уровень для вас? Поскольку вы указали python как тег, я уверен, что в Python есть библиотеки триангуляции Delaunay, которые, по моему мнению, являются самой сложной частью реализации алгоритма; вам просто нужно убедиться, что вы можете изменить полученный результат триангуляции. Функции граничных запросов, вероятно, могут быть реализованы с помощью ассоциативных массивов.
Я проверил следующее, и это работает. Ответ от gordyii был близок, но умножил 100 в неправильном месте и пропустил несколько скобок.
Select Grade, (Count(Grade)* 100 / (Select Count(*) From MyTable)) as Score
From MyTable
Group By Grade
Вам необходимо подсчитать общее количество оценок Если это SQL 2005, вы можете использовать CTE
WITH Tot(Total) (
SELECT COUNT(*) FROM table
)
SELECT Grade, COUNT(*) / Total * 100
--, CONVERT(VARCHAR, COUNT(*) / Total * 100) + '%' -- With percentage sign
--, CONVERT(VARCHAR, ROUND(COUNT(*) / Total * 100, -2)) + '%' -- With Round
FROM table
GROUP BY Grade
Вам нужно сгруппироваться по полю оценки. Этот запрос должен дать вам то, что вы ищете практически в любой базе данных.
Select Grade, CountofGrade / sum(CountofGrade) *100
from
(
Select Grade, Count(*) as CountofGrade
From Grades
Group By Grade) as sub
Group by Grade
Вы должны указать систему, которую используете.
Это, я считаю, общее решение, хотя я тестировал его с использованием IBM Informix Dynamic Server 11.50.FC3. Следующий запрос:
SELECT grade,
ROUND(100.0 * grade_sum / (SELECT COUNT(*) FROM grades), 2) AS pct_of_grades
FROM (SELECT grade, COUNT(*) AS grade_sum
FROM grades
GROUP BY grade
)
ORDER BY grade;
дает следующий вывод на тестовые данные, показанные под горизонтальным правилом. Функция ROUND
может быть специфичной для СУБД, но остальное (вероятно) - нет. (Обратите внимание, что я изменил 100 на 100,0, чтобы гарантировать, что вычисление происходит с использованием нецелого числа - DECIMAL, NUMERIC - арифметика; см. Комментарии и спасибо Thunder.)
grade pct_of_grades
CHAR(1) DECIMAL(32,2)
A 32.26
B 16.13
C 12.90
D 12.90
E 9.68
F 16.13
CREATE TABLE grades
(
id VARCHAR(10) NOT NULL,
grade CHAR(1) NOT NULL CHECK (grade MATCHES '[ABCDEF]')
);
INSERT INTO grades VALUES('1001', 'A');
INSERT INTO grades VALUES('1002', 'B');
INSERT INTO grades VALUES('1003', 'F');
INSERT INTO grades VALUES('1004', 'C');
INSERT INTO grades VALUES('1005', 'D');
INSERT INTO grades VALUES('1006', 'A');
INSERT INTO grades VALUES('1007', 'F');
INSERT INTO grades VALUES('1008', 'C');
INSERT INTO grades VALUES('1009', 'A');
INSERT INTO grades VALUES('1010', 'E');
INSERT INTO grades VALUES('1001', 'A');
INSERT INTO grades VALUES('1012', 'F');
INSERT INTO grades VALUES('1013', 'D');
INSERT INTO grades VALUES('1014', 'B');
INSERT INTO grades VALUES('1015', 'E');
INSERT INTO grades VALUES('1016', 'A');
INSERT INTO grades VALUES('1017', 'F');
INSERT INTO grades VALUES('1018', 'B');
INSERT INTO grades VALUES('1019', 'C');
INSERT INTO grades VALUES('1020', 'A');
INSERT INTO grades VALUES('1021', 'A');
INSERT INTO grades VALUES('1022', 'E');
INSERT INTO grades VALUES('1023', 'D');
INSERT INTO grades VALUES('1024', 'B');
INSERT INTO grades VALUES('1025', 'A');
INSERT INTO grades VALUES('1026', 'A');
INSERT INTO grades VALUES('1027', 'D');
INSERT INTO grades VALUES('1028', 'B');
INSERT INTO grades VALUES('1029', 'A');
INSERT INTO grades VALUES('1030', 'C');
INSERT INTO grades VALUES('1031', 'F');
Должно работать следующее
ID - Key
Grade - A,B,C,D...
РЕДАКТИРОВАТЬ: Переместил * 100
и добавили 1.0
, чтобы гарантировать, что он не выполняет целочисленное деление
Select
Grade, Count(ID) * 100.0 / ((Select Count(ID) From MyTable) * 1.0)
From MyTable
Group By Grade
Проблема:
В Lgi.dll определен другой класс, который экспортирует экземпляр GArray.
#ifdef LGI_DLL
#define LgiClass __declspec(dllexport)
#else
#define LgiClass __declspec(dllimport)
#endif
class LgiClass GToken : public GArray<char*>
{
/// stuff...
};
Решение:
Включите этот заголовок GToken в мой EXE-файл, в частности файл FrameStore.cpp, который использует реализацию GArray, тогда компиляция будет импортировать эти символы из DLL, а не дублировать их.
Было бы неплохо, если бы компилятор мог дайте мне больше подсказки о том, где DLL определяет символ. Простое высказывание «где-то дубликат» не очень полезно.
declare @countOfAll decimal(18, 4)
select @countOfAll = COUNT(*) from Grades
select
Grade, COUNT(*) / @countOfAll * 100
from Grades
group by Grade
Вы можете использовать подвыбор в запросе от (непроверенный и не уверен, что быстрее):
SELECT Grade, COUNT(*) / TotalRows
FROM (SELECT Grade, COUNT(*) As TotalRows
FROM myTable) Grades
GROUP BY Grade, TotalRows
Или
SELECT Grade, SUM(PartialCount)
FROM (SELECT Grade, 1/COUNT(*) AS PartialCount
FROM myTable) Grades
GROUP BY Grade
Или
SELECT Grade, GradeCount / SUM(GradeCount)
FROM (SELECT Grade, COUNT(*) As GradeCount
FROM myTable
GROUP BY Grade) Grades
Вы также можете использовать хранимую процедуру (извинения за синтаксис Firebird):
SELECT COUNT(*)
FROM myTable
INTO :TotalCount;
FOR SELECT Grade, COUNT(*)
FROM myTable
GROUP BY Grade
INTO :Grade, :GradeCount
DO
BEGIN
Percent = :GradeCount / :TotalCount;
SUSPEND;
END
Instead of using a separate CTE to get the total, you can use a window function without the "partition by" clause.
If you are using:
count(*)
to get the count for a group, you can use:
sum(count(*)) over ()
to get the total count.
For example:
select Grade, 100. * count(*) / sum(count(*)) over ()
from table
group by Grade;
It tends to be faster in my experience, but I think it might internally use a temp table in some cases (I've seen "Worktable" when running with "set statistics io on").
EDIT: I'm not sure if my example query is what you are looking for, I was just illustrating how the windowing functions work.