Как найти проценты sql

This is, I believe, a general solution, though I tested it using IBM Informix Dynamic Server 11.50.FC3. The following query:

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;

gives the following output on the test data shown below the horizontal rule. The ROUND function may be DBMS-specific, but the rest (probably) is not. (Note that I changed 100 to 100.0 to ensure that the calculation occurs using non-integer – DECIMAL, NUMERIC – arithmetic; see the comments, and thanks to 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');

I have to calculate percentage based on count. Given below is a sample data table.

TeamName   Count1   Count0
--------   -----    ------
Team1        1        2
Team2        3        0
Team3        1        1

I want to display the percentage based on the greatest value in Count1. The expecting output sample is given below:

Expecting Out Put :

TeamName   Count1   Count0  Percentage1  Percentage0
--------   -----    ------  -----------  -----------
Team1        1        2        33.33%         66.6%
Team2        3        0        100%           0%
Team3        1        1        33.33%         33.33%  

Help me to find a proper solution. Thank You.

asked Jan 16, 2015 at 10:37

vipin tp's user avatar

5

use Max()over () trick to find the max of all the row.

select TeamName,   
Count1,  
Count0,
(count1*100.0)/nullif(Max(Count1) over(),0) Percentage1,
(count0*100.0)/nullif(max(Count1) over(),0) Percentage2
from yourtable

or Use a subquery to find the Max and do the math

SELECT 
  TeamName, 
  Count1, 
  Count0, 
  (Count1*100.0) / nullif((SELECT max(Count1) FROM yourTable),0) Percentage1, 
  (Count0*100.0) / nullif((SELECT max(Count1) FROM yourTable),0) Percentage2
FROM yourTable

answered Jan 16, 2015 at 10:40

Pரதீப்'s user avatar

Pரதீப்Pரதீப்

91.2k18 gold badges130 silver badges168 bronze badges

9

SELECT 
  TeamName, 
  Count1, 
  Count0, 
  Count1 / (SELECT MAX(Count1) FROM Tbl), 
  Count0 / (SELECT MAX(Count1) FROM Tbl) 
FROM Tbl

What out for zero values in Count1. I can improve answer, if you describe case what to do when MAX(Count1) is zero.

answered Jan 16, 2015 at 10:40

Taras Velykyy's user avatar

Taras VelykyyTaras Velykyy

1,7711 gold badge16 silver badges30 bronze badges

Maybe this will help you:

SELECT a.TeamName,
       a.Count1,
       a.Count0,
       a.Count1 / b.maxCount * 100
       a.Count0 / b.maxCount * 100
  FROM yourTable a
  JOIN(SELECT MAX(Count1) 
         FROM yourTable
      ) b
    ON 1 = 1;

answered Jan 16, 2015 at 10:48

DirkNM's user avatar

DirkNMDirkNM

2,61414 silver badges21 bronze badges

try this.

create table tbl(teamname nvarchar(100), count1  int, count2  int)

insert into tbl values
('T1',1,2), ('T2',3,0), ('T3',1,1)

select 
    teamname,
    count1,    
    count2,
    count1 * 100 /(count1 + count2) Percenta1,
    count2 * 100 /(count1 + count2) Percenta2   

From tbl

drop table tbl

answered Jan 16, 2015 at 10:48

Ajay2707's user avatar

Ajay2707Ajay2707

5,6566 gold badges40 silver badges58 bronze badges

looking at your question, it seems if value is 1 then it is 33.33%, for 2 it is 66.6% & for 3 it is 100%. in this case yuo can try below:

SELECT COUNT1, COUNT0,
DECODE(COUNT1,1,'33.33%',2,'66.6%',3,'100%') PERCENTAGE1,
DECODE(COUNT0,1,'33.33%',2,'66.6%',3,'100%') PERCENTAGE0
FROM tablename;

if it is not the case, then please explain why for row3 in your table, both percentage1 and 0 are 33.33 %

answered Jan 16, 2015 at 10:58

Shantanu's user avatar

ShantanuShantanu

1861 silver badge8 bronze badges

  • How-Tos FAQs
  • December 17, 2018

Supercharge Your Snowflake SQL
with Datameer's
Data Transformation

There are different ways to calculate percentage in SQL like:

  • Using Ratio_to_report() function or the Percent_Rank function
  • Using OVER() clause
  • Using subquery
  • Using CTE

Calculating percentage in SQL

    Let us consider the ‘inventory’ table as below. We can calculate the percentage of each item in the inventory.

    CREATE TABLE inventory(
           item VARCHAR(50),
           avail_stock INT
    );
    
    INSERT INTO inventory
    SELECT 'laptop', 20 UNION ALL
    SELECT 'keyboard', 40 UNION ALL
    SELECT 'mouse', 70 UNION ALL
    SELECT 'speaker', 20 UNION ALL
    SELECT 'Monitor', 50;

    Snowflake SQL

    In Snowflake, you can use the Ratio_to_report() function or the Percent_Rank function, depending on your use case.

    RATIO_TO_REPORT()
    select
        item,
        stock,
        ratio_to_report(stock) over () as overall_stock_pct
    from inventory

    Keep Tabs on your “Calculated(%)” SQL Using Datameer’s Graphical Interface

    Datameer is a collaborative, multi-persona data transformation platform that integrates with Snowflake.

    With Datameer on Snowflake, you can use the SQL functions you’re familiar with to calculate your percentage and visually track all your calculated percentage queries with our low-code GUI interface.

    To reap the benefits of these easy drag-and-drop modeling and self-documenting features, kickstart your Snowflake instance and connect your Datameer account.

    SQL SERVER

    -- Using OVER Clause
    SELECT item Item, avail_stock * 100.0/ SUM(avail_stock) OVER() 'Percentage(%)'
    FROM inventory
    
    -- Using CROSS APPLY
    SELECT item Item, avail_stock * 100.0/ sub.sum_avail_stock 'Percentage(%)'
    FROM inventory
    CROSS APPLY (SELECT SUM(avail_stock) sum_avail_stock FROM inventory) sub
    
    -- Using subquery in SELECT statement
    SELECT item Item, avail_stock * 100.0/ (SELECT SUM(avail_stock) FROM inventory) 'Percentage(%)'
    FROM inventory
    
    -- Using CTE
    ;WITH total AS
    (
          SELECT SUM(avail_stock) AS total
        FROM inventory
    )
    SELECT item Item,
        avail_stock * 100 / total.total AS 'Percentage(%)'
    FROM inventory
    CROSS JOIN total;
    
    -- Output of all above queries
    Item        Percentage(%)
    ----------------------------
    laptop      10.000000000000
    keyboard    20.000000000000
    mouse       35.000000000000
    speaker     10.000000000000
    Monitor     25.000000000000

    MySQL

    -- Using OVER Clause
    SELECT item Item, avail_stock * 100.0/ SUM(avail_stock) OVER() 'Percentage(%)'
    FROM inventory;
    
    -- Using Subquery in SELECT statement
    SELECT item Item, avail_stock * 100.0/ (SELECT SUM(avail_stock) FROM inventory) 'Percentage(%)'
    FROM inventory;
    
    -- Using CROSS JOIN
    SELECT item Item, avail_stock * 100/ sub.sum_avail_stock 'Percentage(%)'
    FROM inventory
    CROSS JOIN (SELECT SUM(avail_stock) sum_avail_stock FROM inventory) sub;
    
    -- Output of all above queries
    Item       Percentage(%)
    ----------------------------
    laptop     10.000000000000
    keyboard   20.000000000000
    mouse      35.000000000000
    speaker    10.000000000000
    Monitor    25.000000000000

    Up Next:

    Read In SQL, how to limit the number of rows after ordering it in Oracle DB?

    SQL > Advanced SQL >
    Percent To Total

    To calculate percent to total in SQL, we need to first calculate the total, and then we divide each individual value by the total to find the percentage. So this is a two-step process. There are multiple ways to accomplish this. Here we will show three different ways:

    • Inline View in SELECT
    • Inline View in FROM
    • Using Common Table Expression (CTE)

    Inline View in SELECT

    The first method is to use the inline view construct in the SELECT statement. The idea here is to treat the total as a single number that we can directly use as the denominator in the division.

    Let’s use an example to illustrate. Say we have the following table,

    Table Total_Sales

     Name   Sales 
     John   10 
     Jennifer   15 
     Stella   20 
     Sophia   40 
     Greg   50 
     Jeff   20 

    we would type,

    SELECT a1.Name, a1.Sales, a1.Sales * 1.0/(SELECT SUM(Sales) FROM Total_Sales) Pct_To_Total

    FROM Total_Sales a1

    ORDER BY a1.Sales DESC, a1.Name DESC;

    Result:

    Name  Sales  Pct_To_Total
    Greg  50 0.3226
    Sophia  40 0.2581
    Stella  20 0.1290
    Jeff  20 0.1290
    Jennifer  15 0.0968
    John  10 0.0645

    The inline view SELECT SUM(Sales) FROM Total_Sales calculates the sum. We can then divide the individual values by this sum to obtain the percent to total for each row.

    We include * 1.0 because in some databases (such as SQLite), dividing an integer by another integer results in an integer, which is not what we want. Multiplying the numerator by 1.0 forces the expression to be considered as a float by the database, and the result of the division will have the float data type, which is what we want.

    Inline View in FROM

    The second method is to the inline view in the FROM statement. Here, the inline view essentially becomes another table that you can query from. Note that here we do not need to specify the join condition between the two tables, as the inline view only has a single column and a single row. In this case, the SQL would become as follows:

    SELECT a1.Name, a1.Sales, a1.Sales * 1.0 / a2.Total Pct_To_Total

    FROM Total_Sales a1, (SELECT SUM(Sales) Total FROM Total_Sales) a2

    ORDER BY a1.Sales DESC, a1.Name DESC;

    Using Common Table Expression (CTE)

    A third way to calculate percent to total is to use the Common Table Expression (CTE). In this case, we will first use the WITH statement to calculate the total, and then use the result in the main query to calculate the percent to total. In our example, the SQL would look like the following:

    WITH Total_Sum AS (

    SELECT SUM(Sales) Total FROM Total_Sales

    )

    SELECT a1.Name, a1.Sales, a1.Sales * 1.0 / a2.Total Pct_To_Total

    FROM Total_Sales a1, Total_Sum a2

    ORDER BY a1.Sales DESC, a1.Name DESC;

    List of SQL Complex Operations

     Operation  Description
     Rank   Calculates the ranking of a series of numbers. 
     Median   Calculates the median of a series of numbers. 
     Running Totals   Calculates the running total for a series of numbers. 
     Percent To Total   Calculates the percent to total for each number in a series. 
     Cumulative Percent To Total   Calculates the cumulative percent to total for each number in a series. 

    Next: SQL Cumulative Percent To Total
    This page was last updated on June 19, 2022.


    Copyright © 2023   1keydata.com   All Rights Reserved  
      Privacy Policy     About   Contact

    Вы уж извините, но то что Вы написали в запросе … это даже приблизительно не то что Вы хотели получить на словах.
    Да и на словах как то все поплыло “Вывести всех клиентов, у которых есть 5 пар клиентов” – кто на ком стоял?

    Если в 2 словах по запросу, у Вас 2 LEFT JOIN, оба не нужны.
    У Вас нет вообще связки между двумя экземплярами orders, да и не надо там 2 раза.
    Ну в целом …. работает долго и непонятно, будет данных больше, будет работать днями …

    P.S. после долгих уточнений подходящий ответ такой, для MySQL 8+

    select af_id, sum(coalesce(amount_value,0))*0.1 sum_pair_10
    from (
            select 
            arur.af_id,
            arur.r_w_uid,
            lag(arur.r_w_uid,1,-1) over (partition by arur.af_id order by arur.r_w_uid) r_w_uid_1
            ,row_number() OVER (partition by arur.af_id order by arur.r_w_uid ) mod 2 pair_flag
            
            from arur, u_af 
            where u_af.id = arur.af_id ) t1  left join orders o on (o.uid in (t1.r_w_uid,t1.r_w_uid_1) and o.status = 'Completed')
    where pair_flag = 0
    group by af_id
    having count(distinct r_w_uid) >  5

    Для более младших версий

    select af_id, sum(coalesce(amount_value,0))*0.1 sum_pair_10
    from (SELECT arur.af_id,
           arur.r_w_uid, 
           @row_num :=  CASE WHEN @row_num_val = af_id                THEN @row_num+1
                             WHEN (@row_num_val := af_id) IS NOT NULL THEN 1
                        END   pair_flag,
           @lag_r_w_uid :=  CASE WHEN (@row_num_val = af_id) and @row_num mod 2 = 1 THEN r_w_uid
                                 else @lag_r_w_uid
                            END r_w_uid_1     
    
    FROM arur, u_af, (SELECT @row_num := null, @row_num_val := null, @lag_r_w_uid := null) AS x
    where u_af.id = arur.af_id 
    ORDER BY af_id, r_w_uid        ) t1  left join orders o on (o.uid in (t1.r_w_uid,t1.r_w_uid_1) and o.status = 'Completed')
    where pair_flag mod 2 = 0
    group by af_id
    having count(distinct r_w_uid) >  5

    Добавить комментарий