কীভাবে এসকিউএল স্টেটমেন্ট দিয়ে শতাংশ গণনা করবেন


177

আমার একটি এসকিউএল সার্ভারের টেবিল রয়েছে যাতে ব্যবহারকারী এবং তাদের গ্রেড রয়েছে। সরলতার জন্য, কেবল এটির জন্য 2 টি কলাম বলা যাক -name এবং grade। সুতরাং একটি সাধারণ সারিটির নাম হবে: "জন ডো", গ্রেড: "এ"।

আমি একটি এসকিউএল বিবৃতি খুঁজছি যা সমস্ত সম্ভাব্য উত্তরের শতাংশ খুঁজে পাবে। (এ, বি, সি, ইত্যাদি ...) এছাড়াও, সমস্ত সম্ভাব্য উত্তরগুলি সংজ্ঞায়িত না করে এটি করার একটি উপায় আছে (উন্মুক্ত পাঠ্য ক্ষেত্র - ব্যবহারকারীরা 'পাস / ফেল', 'কিছুই না' ইত্যাদি লিখতে পারে ...)

আমি যে চূড়ান্ত আউটপুটটি সন্ধান করছি তা হ'ল এ: 5%, বি: 15%, সি: 40%, ইত্যাদি ...

উত্তর:


227

আমি নিম্নলিখিতটি পরীক্ষা করেছি এবং এটি কাজ করে। গর্ডিয়াইয়ের উত্তরটি নিকটে ছিল তবে এটি ভুল জায়গায় 100 এর গুণক ছিল এবং এর কিছু অনুপস্থিত বন্ধনী ছিল।

Select Grade, (Count(Grade)* 100 / (Select Count(*) From MyTable)) as Score
From MyTable
Group By Grade

21
এটি পূর্ণসংখ্যায় ফলাফল দেয়। ফলাফলের পরিমাণ 100 এর সমান নয়
থান্ডার

10
সারণীটি দু'বার স্ক্যান করা হওয়ায় সবচেয়ে কার্যকর নয়। এছাড়াও যদি একাধিক টেবিল রেফারেন্সযুক্ত থাকে তবে কোয়েরিটি এত সহজ দেখাচ্ছে না।
অ্যালেক্স আজা

14
@ থান্ডার দশমিক মানগুলির জন্য আপনি 100 থেকে 100.0 এ পরিবর্তন করতে পারেন।
জোসেফ

কেউ যদি ব্যাখ্যা করতে পারে যে এসকিউএল ক্যোয়ারীর গাণিতিক বাক্য গঠনটি আপনি সাধারণত যা করতে চান তা না কেন? উদাহরণস্বরূপ, আমি মোটের সাথে ভাগ করে 100 করে গুণব? একটি যৌক্তিক স্ট্যান্ড পয়েন্ট থেকে সত্যই কৌতূহলী।
Digitalsa1nt

4
@ Digitalsa1nt (100 * 2) / 4 = 50, (2/4) * 100 = 50 যতক্ষণ এনুনিমেটার হয় সে অংশটি বহুগুণে বৃদ্ধি পাচ্ছে। এসকিউএল বিবৃতিগুলির অগ্রাধিকারের কারণে এটি একই হবে। তবে তথ্যের ধরণের কারণে যদি 100 ব্যবহার করে আপনি এখনও ফলাফলটি% 0 এর জন্য গোল করে পেতে পারেন যেখানে বিভাগীয় ক্রিয়াকলাপের পরে আপনি এটি রেখেছেন তা নিশ্চিত করতে হবে যে আপনি এমন কোনও ডেটা টাইপ করেছেন যা হ্যান্ডেল করতে পারে দশমিক স্থানগুলি অন্যথায় আপনি 100 বা 0 দিয়ে শেষ করবেন এবং কখনও আসল শতাংশ হবে না
ম্যাট

231
  1. সর্বাধিক দক্ষ (ওভার () ব্যবহার করে)।

    select Grade, count(*) * 100.0 / sum(count(*)) over()
    from MyTable
    group by Grade
  2. ইউনিভার্সাল (যে কোনও এসকিউএল সংস্করণ)।

    select Grade, count(*) * 100.0 / (select count(*) from MyTable)
    from MyTable
    group by Grade;
  3. সিটিই সহ, সবচেয়ে কম দক্ষ।

    with t(Grade, GradeCount) 
    as 
    ( 
        select Grade, count(*) 
        from MyTable
        group by Grade
    )
    select Grade, GradeCount * 100.0/(select sum(GradeCount) from t)
    from t;

13
ওভার () আমার এসকিউএল সার্ভার ২০০৮ এ পুরোপুরি কাজ করেছে, আমি তা নিশ্চিত করার জন্য গণিতটি করেছি। এটিকে 2 দশমিক স্থানে নিয়ে যাওয়ার জন্য আমি CAST (গণনা ( ) * 100.0 / যোগ (গণনা ( )) ওভার () এএস ডেসিমাল (18, 2)) ব্যবহার করেছি। পোস্টের জন্য ধন্যবাদ!
আরজেবি

3
যদি আপনি 100 গুণকে (যেমন গাণিতিক ওভারফ্লো ত্রুটি এক্সপ্রেশনটি ডেটা টাইপ ইনটকে রূপান্তর করে ) উপচে পড়ে যান তবে এর পরিবর্তে ডিনোমিনেটরে বিভাজন স্থাপন করুন:cast((count(*) / (sum(count(*)) over() / 100)) AS DECIMAL(18, 2)) as Percentage
নিকিতা জি।

@ আরজেবি আপনি যখন দশমিক হিসাবে আউটপুট কাস্ট করছেন তখন আপনাকে কেন 100.0 দিয়ে গুণতে হবে?
AS91

2
@ AS91, কারণ বিভাগের কাজকর্মের পরে দশমিকের কাস্টটি ঘটে। আপনি যদি কোন int (100) রেখে যান তবে অন্য কোনও int দিয়ে ভাগ করার ফলে ফলাফলের পরিমাণও ঘটাবে int এই কারণেই ট্রিকটি সর্বদা ডিভিডেন্ডে আসল বিভাগের পূর্বে একটি
কাস্টটিকে বাধ্য করা

অপশন 1 over()পোস্টগ্র্রেসক্লল 10
জেমস ডেইলি

40

মোটটি পাওয়ার জন্য পৃথক সিটিই ব্যবহার না করে আপনি "বিভাজন দ্বারা" ধারাটিতে উইন্ডো ফাংশনটি ব্যবহার করতে পারেন।

আপনি যদি ব্যবহার করছেন:

count(*)

একটি গোষ্ঠীর জন্য গণনা পেতে, আপনি ব্যবহার করতে পারেন:

sum(count(*)) over ()

মোট গণনা পেতে।

উদাহরণ স্বরূপ:

select Grade, 100. * count(*) / sum(count(*)) over ()
from table
group by Grade;

এটি আমার অভিজ্ঞতায় দ্রুততর হতে থাকে, তবে আমি মনে করি এটি অভ্যন্তরীণভাবে কোনও কোনও ক্ষেত্রে একটি টেম্প টেবিল ব্যবহার করতে পারে ("সেট পরিসংখ্যান আইও অন" দিয়ে চলার সময় আমি "ওয়ার্কটেবল" দেখেছি)।

সম্পাদনা: আমি নিশ্চিত নই যে আমার উদাহরণের ক্যোয়ারী আপনি যা খুঁজছেন তা হ'ল, আমি কীভাবে উইন্ডোটিং ফাংশনগুলি কাজ করে তা চিত্রিত করছিলাম।


+1 টি। এটা অসাধারণ. এটি যদি টেবিলের জায়গায় একটি নির্বাচনী বিবৃতি উপস্থিত থাকে তবে এটি ব্যবহার করা যেতে পারে।
mr_georg

1
এটি একটি স্পুল ব্যবহার করে tempdbযাতে কাজের সারণী। যৌক্তিক পাঠগুলি উচ্চতর বলে মনে হয় তবে এগুলি স্বাভাবিকের চেয়ে পৃথকভাবে গণনা করা হয়
মার্টিন স্মিথ

1
প্রকৃতপক্ষে, COUNT(*) OVER ()আপনার ক্যোয়ারিতে থাকা সম্পূর্ণরূপে সম্পর্কিত নয় এমন চিত্র ফিরিয়ে দেবে (বিশেষত, গোষ্ঠীভিত্তিক ফলাফলের সারিগুলির সংখ্যা )। SUM(COUNT(*)) OVER ()পরিবর্তে আপনার ব্যবহার করা উচিত ।
অ্যান্ড্রি এম

10

আপনাকে মোট গ্রেডের গণনা করতে হবে যদি এটি এসকিউএল 2005 হয় তবে আপনি সিটিই ব্যবহার করতে পারেন

    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

1
অবশ্যই, এটি কেবল সারণীতে উপস্থিত গ্রেড কোডগুলির শতাংশ দেয়, যা উপস্থিত হতে পারে এবং না তাদের জন্য নয়। তবে প্রাসঙ্গিক (বৈধ) গ্রেড কোডগুলির একটি নির্দিষ্ট তালিকা ছাড়াই আপনি আরও ভাল করতে পারবেন না। সুতরাং আমার কাছ থেকে +1
জোনাথন লেফলার

1
আমার জন্য লুকানো রত্নটি আপনি মন্তব্য করা হয়েছিল।
ক্রিস ক্যাটিগনি

9

আপনার গ্রেড মাঠে দলবদ্ধ করা দরকার। এই কোয়েরিতে আপনাকে যে কোনও ডাটাবেসটিতে যা খুঁজছে তা দেওয়া উচিত।

    Select Grade, CountofGrade / sum(CountofGrade) *100 
    from
    (
    Select Grade, Count(*) as CountofGrade
    From Grades
    Group By Grade) as sub
    Group by Grade

আপনি যে সিস্টেমটি ব্যবহার করছেন তা আপনার নির্দিষ্ট করা উচিত।


2
যেহেতু আপনার বাহ্যিক নির্বাচনের মধ্যে একটি সমষ্টি ('যোগফল (গণনাগ্রহ)' রয়েছে, সুতরাং আপনারও কি এটির ধারাতে কোনও গ্রুপের দরকার নেই? এবং স্ট্যান্ডার্ড এসকিউএল-তে আমার মনে হয় আপনি গ্র্যান্ড টোটাল পেতে '/ (নির্বাচন গ্রেডগুলি (*) থেকে' নির্বাচন করতে পারেন)।
জোনাথন লেফলার

আইবিএম ইনফর্মিক্স ডায়নামিক সার্ভার সিলেক্ট-লিস্টে নগ্ন এসইউএম পছন্দ করে না (যদিও এটি অভিযোগ করলে এটি কিছুটা কম-সহায়ক বার্তা দেয়)। আমার উত্তর এবং পূর্বের মন্তব্যে উল্লিখিত হিসাবে, বাছাই-তালিকায় একটি সম্পূর্ণ উপ-নির্বাচন এক্সপ্রেশন ব্যবহার করে আইডিএসে কাজ করে।
জোনাথন লেফলার

এটি আরও ভাল কারণ কেউ অভ্যন্তরীণ কোয়েরিতে জটিল প্রয়োগ করতে পারে।
এমভিএমএন

9

আমি যখন কেবল শতাংশের বাইরে কাজ করতে পারি তখনই আমি এটি ব্যবহার করি ..

ROUND(CAST((Numerator * 100.0 / Denominator) AS FLOAT), 2) AS Percentage

নোট করুন যে ১০০.০ দশমিককে রিটার্ন দেয়, যেখানে তার নিজস্ব ১০০ ফলাফলটি রাউন্ড () ফাংশন সহ এমনকি নিকটতম পুরো সংখ্যায় গোল করে দেয়!


7

নিম্নলিখিত কাজ করা উচিত

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

1
এটি কাজ করে, তবে সমস্ত উত্তরগুলি 0 হিসাবে ফিরে আসে - সঠিক উত্তরটি দেখার জন্য আমাকে কি কিছু ধরণের ফর্ম্যাটিং বা রূপান্তর করতে হবে?
অ্যালেক্স

1
বর্গ
থান্ডার

5

এটি আমি বিশ্বাস করি, এটি একটি সাধারণ সমাধান, যদিও আমি এটি আইবিএম ইনফর্মিক্স ডায়নামিক সার্ভার ১১.৫০.এফসি 3 ব্যবহার করে পরীক্ষা করেছি। নিম্নলিখিত কোয়েরি:

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ফাংশন DBMS-নির্দিষ্ট হতে পারে, কিন্তু বাকি (সম্ভবত) নয়। (নোট করুন যে গণনাটি অ-পূর্ণসংখ্যার - ডেসিমাল, NUMERIC - গাণিতিক ব্যবহার করে গণনা ঘটে কিনা তা নিশ্চিত করার জন্য আমি 100 থেকে 100.0 এ পরিবর্তন করেছি; মন্তব্যগুলি দেখুন এবং থান্ডারকে ধন্যবাদ।)

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');


@ থান্ডার: আকর্ষণীয়; আপনি যদি 100 থেকে 100.00 পরিবর্তন করেন তবে কী হবে?
জোনাথন লেফলার

অবশ্যই ফলাফলটি দশমিকের সাথে 100.0
থান্ডার

4
SELECT Grade, GradeCount / SUM(GradeCount)
FROM (SELECT Grade, COUNT(*) As GradeCount
      FROM myTable
      GROUP BY Grade) Grades

3

যে কোনও এসকিএল সার্ভার সংস্করণে আপনি এই জাতীয় সমস্ত গ্রেডের মোটের জন্য একটি ভেরিয়েবল ব্যবহার করতে পারেন:

declare @countOfAll decimal(18, 4)
select @countOfAll = COUNT(*) from Grades

select
Grade,  COUNT(*) / @countOfAll * 100
from Grades
group by Grade

3

আপনি আপনার ক্যোয়ারী থেকে একটি সাব-সাবলেট ব্যবহার করতে পারেন (যাচাই করা হয়নি এবং কোনটি দ্রুত তা নিশ্চিত নয়):

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

আপনি একটি সঞ্চিত পদ্ধতিও ব্যবহার করতে পারেন (ফায়ারবার্ড সিনট্যাক্সের জন্য ক্ষমা প্রার্থনা):

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

0

আমি এই একই সমস্যা ছিল। আপনার সঠিক ফলাফলটি 100 এর পরিবর্তে ০.০ দিয়ে গুণ করা সম্ভব হবে example উদাহরণটি চিত্র সংযুক্ত দেখুন

গ্রেড অনুসারে মাই টেবিল গ্রুপ থেকে স্কোর হিসাবে গ্রেড, (গণনা (গ্রেড) * 1.0 / (মাই টেবিল থেকে গণনা (*) নির্বাচন করুন) নির্বাচন করুন সংযুক্ত রেফারেন্স চিত্র দেখুন


একেবারে প্রয়োজনীয় না হলে ছবি হিসাবে তথ্য ভাগ করবেন না দয়া করে। দেখুন: মেটা.স্ট্যাকওভারফ্লো / প্রশ্ন / 303812/…
এএমসি

0

এই এক এমএস এসকিউএল ভাল কাজ করছে। এটি দ্বি-দশমিক-স্থান-সীমাবদ্ধ ভাসমানের ফলকে বার্চারে রূপান্তরিত করে।

Select field1, cast(Try_convert(float,(Count(field2)* 100) / 
Try_convert(float, (Select Count(*) From table1))) as decimal(10,2)) as new_field_name 
From table1 
Group By field1, field2;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.