Consulta Sql para obtener los valores basados ​​​​en% de entrada

Tengo una mesa como la de abajo

 Board Component Cost

    b1     c1       5
    b1     c2       10
    b2     c3       15
    b3     c4       20
    b3     c5       25
    b4     C6       25
  ---------------------
                  100%

Debería dar la entrada para obtener los valores de la tabla, digamos ...

Si la entrada es 20%

la salida debe ser

 Board Component Cost

    b1      c1      5
    b1      c2     10
    b2      c3     15

Si la entrada es 50%

la salida debe ser

 Board Component Cost

    b1      c1      5
    b1      c2     10
    b2      c3     15
    b3      c4     20

y así

Cómo escribir la consulta en el servidor sql

preguntado el 22 de mayo de 12 a las 10:05

Con el 50%, ¿por qué no los dos últimos? ¿Deberíamos seleccionar de arriba a abajo? -

¿No debería el 20% ser el 30%? ¿Quieres sumar partes hasta llegar a cierto porcentaje? -

¿Por qué quieres ordenar? -

Esto suena como el problema de la suma de subconjuntos en.wikipedia.org/wiki/Subset_sum_problem -

Sí, primero necesito ordenar para entonces de menor a mayor -

5 Respuestas

DECLARE @T TABLE (Col1 VARCHAR(10), Col2 VARCHAR(10), Col3 INT, SumValue Int)

INSERT INTO @T(Col1, Col2, Col3)
VALUES ('b1','c1',5)

INSERT INTO @T(Col1, Col2, Col3)
VALUES ('b1','c2',10)

INSERT INTO @T(Col1, Col2, Col3)
VALUES ('b2','c3',15)

INSERT INTO @T(Col1, Col2, Col3)
VALUES ('b3','c4',20)

INSERT INTO @T(Col1, Col2, Col3)
VALUES ('b3','c5',25)

INSERT INTO @T(Col1, Col2, Col3)
VALUES ('b4','C6',25) 

DECLARE @SumValue INT

UPDATE @T
SET @SumValue=SumValue = ISNULL(@SumValue,0)+ Col3
FROM @T T

SELECT *
FROM @T
WHERE SumValue <= (
    SELECT TOP 1 SumValue
    FROM @T AS T
    WHERE T.SumValue>=40
    ORDER BY SumValue)

contestado el 22 de mayo de 12 a las 12:05

Primero, dado que necesitamos agrupar y sumar valores anteriores, necesitará una Identidad para implementar esto. Espero que se te ocurra uno. Creé esta tabla para simular tu situación:

create table mySUM(
id int identity(1,1),
id2 varchar(50),
cost int)

insert into mySUM values
('c1',  5),   ('b1', 10),    ('b2',15),    ('b3',20),    ('b3',25),    ('b4',25)

Tengo dos selecciones para ti. Este es el principal pero, como estamos agrupando y sumando, resultará la suma en la última columna:

select a.Id, a.id2, sum(b.cost) as totalCost
from mySUM a cross join mySUM b
where b.Id <= a.Id
group by a.Id,a.id2
having sum(b.cost)<=50
order by  a.Id

resultado:

1   c1  5
2   b1  15
3   b2  30
4   b3  50

si no desea eso, puede ejecutar una selección en la tabla principal en función de los identificadores de la selección anterior:

select * from mySUM where id in(
    select a.Id
    from mySUM a cross join mySUM b
    where b.Id <= a.Id
    group by a.Id,a.id2
    having sum(b.cost)<=50
)

resultado:

1   c1  5
2   b1  10
3   b2  15
4   b3  20

contestado el 22 de mayo de 12 a las 10:05

Si es el 50%, enumerará todo. sin embargo, no debería, verifique la segunda tabla de salida: somashekhar

sí, leí demasiado rápido. Cambié mi respuesta, por favor echa un vistazo - Diego

Dale una oportunidad

SELECT  t.* ,
        rt.runningTotal
FROM    Test t
        CROSS APPLY ( SELECT    SUM(cost) AS runningTotal
                      FROM      Test
                      WHERE     Board <= t.Board
                                AND Component <= t.Component
                    ) AS rt
WHERE   runningTotal <= 50
ORDER BY t.Board

contestado el 22 de mayo de 12 a las 10:05

Cuando solicita el 20% en su pregunta, devuelve 5+10+15 = 30. ¿No debería ser 5+10=15 ya que es más pequeño que 20? - Buckley

Cambie la cláusula Where interna si los necesita ordenados por Score. La pregunta original no estaba clara en eso y aunque quería ordenar alfabéticamente en las primeras 2 columnas. - Buckley

@Somashekhar Tal vez podría ayudar a sus ayudantes indicando lo que no es correcto: Buckley

prueba esto:

with CTE (Board, Component ,Cost, rownum)
as
(
SELECT Board,Component, Cost,
ROW_NUMBER() OVER(order by Cost asc, Board asc, Component asc) rownum
  FROM yourTable t0
  where Cost > 0
)
select
t1.Board,t1.Component, t1.Cost, t1.rownum, sum(t2.Cost)
from 
CTE t1 join CTE t2 on t1.rownum >= t2.rownum
group by t1.Board,t1.Component, t1. Cost, t1.rownum
having sum(t2.Cost) < 50
order by t1.rownum;

Deberia trabajar

contestado el 22 de mayo de 12 a las 11:05

create table #per(
Board varchar(10),
Component varchar(max),
Cost int)

create proc out_per (
@desire_per int)
as begin

declare @sum int, @count int;
declare @board varchar(max), @component varchar(max);
declare @cost int;
declare per_cursor cursor for
select Board,Component,Cost from per
open per_cursor
fetch next from per_cursor into @Board, @component, @cost
while(@@fetch_status=0)
    begin
        insert into #per values (@Board, @component, @cost);
        set @sum=(select sum(cost) from #per)
        if(@sum>=@desire_per)
        begin
            break;
        end
        fetch next from per_cursor into @Board, @component, @cost
    end
    close per_cursor
    deallocate per_cursor
    select * from #per
    truncate table #per
end

exec out_per @desire_per=30

contestado el 22 de mayo de 12 a las 13:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.