sql >> Database teknologi >  >> RDS >> Sqlserver

SQL - Jeg skal opdele en samlet værdi i flere rækker i en anden tabel

Du kan gøre det sådan, denne forespørgsel udfylder først klasseværelser med størst kapacitet:

DECLARE @School TABLE (School_Id INT,Course_Id 
    VARCHAR(50), Total_Students INT)
DECLARE @Class TABLE (School_Id INT,Course_Id 
    VARCHAR(50), Class_ID VARCHAR(50), Capacity INT)
INSERT @School VALUES 
   (1,         'Acct101'        ,150),
   (1,         'Acct102'        ,100),
   (2,         'Acct101'        ,110),
   (2,         'Acct102'        ,130)
INSERT @Class VALUES 
   (1,         'Acct101'     ,'A1'       ,65),
   (1,         'Acct101'     ,'A2'       ,50),
   (1,         'Acct101'     ,'A3'       ,70),
   (1,         'Acct102'     ,'Ab1'      ,100),
   (1,         'Acct102'     ,'Ab2'      ,100),
   (2,         'Acct101'     ,'B1'       ,80),
   (2,         'Acct101'     ,'B2'       ,90)

;WITH y AS (
SELECT  a.*,
        ROW_NUMBER() OVER 
            (PARTITION BY a.School_ID, a.Course_ID ORDER BY a.Capacity DESC) 
            CapacitiyOrderPerSchoolAndCourse,
        SUM(a.Capacity) OVER 
            (PARTITION BY a.School_ID, a.Course_ID) 
            TotalCapacityForSchoolAndCourse,
        b.Total_Students TotalParticipants
FROM    @Class a
JOIN    @School b ON 
        b.School_Id = a.School_Id
        AND b.Course_Id = a.Course_Id
), z AS(
SELECT  x.School_Id, 
        x.Course_Id, 
        y.TotalCapacityForSchoolAndCourse, 
        y.TotalParticipants,
        CASE WHEN y.TotalParticipants < SUM(x.Capacity) THEN 
                y.TotalParticipants
            ELSE 
                SUM(x.Capacity) 
            END NumberOfStudentsInClasses,
        MIN(y.Capacity) ClassCapacity,
        y.Class_ID ClassName,
        MIN(y.Capacity) - 
        CASE WHEN y.TotalParticipants - SUM(x.Capacity) < 0 THEN 
               ABS(y.TotalParticipants - SUM(x.Capacity))
            ELSE
               0
            END StudentsInClass
FROM    y
JOIN    y x ON x.School_Id = y.School_Id 
        AND x.Course_Id = y.Course_Id 
        AND x.CapacitiyOrderPerSchoolAndCourse 
                <= y.CapacitiyOrderPerSchoolAndCourse
GROUP   BY x.School_Id, 
        x.Course_Id, 
        y.CapacitiyOrderPerSchoolAndCourse, 
        y.Class_ID, 
        y.TotalCapacityForSchoolAndCourse, 
        y.TotalParticipants
)

SELECT  
        z.School_Id, 
        z.Course_Id, 
        z.TotalCapacityForSchoolAndCourse, 
        z.TotalParticipants,
        z.ClassName,
        z.ClassCapacity,
        CASE WHEN StudentsInClass < 0 THEN 
                0 
            ELSE 
                StudentsInClass 
            END StudentsInClass
FROM    z
 

Hvis du ønsker, at hvert klasseværelse skal have et vist antal elever, kan du gøre det på denne måde (det tildeler et antal elever til hvert klasseværelse i henhold til dets kapacitet):

;WITH y AS ( SELECT a.*, SUM(a.Capacity) OVER (PARTITION BY a.School_ID, a.Course_ID) AS TotalCapacityForSchoolAndCourse, b.Total_Students TotalParticipants FROM @Class a JOIN @School b ON b.School_Id = a.School_Id AND b.Course_Id = a.Course_Id ), z AS( SELECT y.School_Id, y.Course_Id, y.TotalCapacityForSchoolAndCourse, y.TotalParticipants, MIN(y.Capacity) ClassCapacity, y.Class_ID, MIN(y.Capacity) * 1.0 / y.TotalCapacityForSchoolAndCourse AS PercentOfCapacity, ROUND( MIN(y.Capacity) * 1.0 / y.TotalCapacityForSchoolAndCourse * TotalParticipants , 0, 0) AS NumberOfStudents FROM y GROUP BY y.School_Id, y.Course_Id, y.Class_ID, y.TotalCapacityForSchoolAndCourse, y.TotalParticipants ) , i AS( SELECT z.School_Id, z.Course_Id, z.TotalCapacityForSchoolAndCourse, z.TotalParticipants, z.Class_ID, z.ClassCapacity, PercentOfCapacity, NumberOfStudents, SUM(NumberOfStudents) OVER (PARTITION BY z.School_Id, z.Course_Id) AS SumNumberOfStudents, ROW_NUMBER() OVER (PARTITION BY z.School_Id, z.Course_Id ORDER BY NumberOfStudents) AS ClassWithSmallestCapacity FROM z ), j AS( SELECT i.School_Id, i.Course_Id, i.TotalCapacityForSchoolAndCourse, i.TotalParticipants, i.Class_ID, i.ClassCapacity, i.PercentOfCapacity, i.NumberOfStudents, i.NumberOfStudents + CASE WHEN ClassWithSmallestCapacity = 1 THEN TotalParticipants - SumNumberOfStudents ELSE 0 END AS NumberOfStudents2 FROM i ) SELECT * FROM j

  1. Sådan forenkler du en udvalgt forespørgsel, der indeholder mange indre selektioner og øger ydeevnen i PostgreSQL

  2. Kan ikke oprette MySQL-trigger med TRIGGER-privilegium på 5.1.32

  3. Sådan indsætter du tags i databasen ved hjælp af jquery html og php

  4. Hvordan får man den automatisk inkrementerede PK fra Oracle-databasen?