powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Можно ли реализовать задачу без условных операторов и циклов?
19 сообщений из 19, страница 1 из 1
Можно ли реализовать задачу без условных операторов и циклов?
    #40005292
арт2010
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть такой запрос
Код: sql
1.
2.
3.
4.
5.
6.
   SELECT idb, clientb, productb, qty_buy,
      (SELECT SUM (qty * price) Profit FROM dbo.Deals WHERE (id < idb) AND (product = productb) AND (client = clientb)
      AND (qty > 0) 
      HAVING SUM(qty) <= qty_buy ) 
    FROM #buy b
    ORDER BY idb


Он работает неправильно, потому что вместо SUM(qty) <= qty_buy должно быть нечто такое:
Код: sql
1.
2.
3.
4.
5.
6.
7.
  sum_qty := 0;
  while sum_qty <= qty_buy do
   begin
    ...
    sum_qty :=  sum_qty + sum_qty(id)
    ...
  end;



Короче мне нужно суммировать не все поле, а только пока сумма значений некоторых его элементов не достигнет определенного значения. Возможно сделать это без условных операторов и циклов чисто средствами T-SQL, подскажите пожалуйста, очень нужно!
...
Рейтинг: 0 / 0
Можно ли реализовать задачу без условных операторов и циклов?
    #40005300
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
арт2010,

Цикл предусматривает упорядоченность строк в таблице Deals. Вы хотите посчитать доход, не выходя за рамки количества товара на складе, и уважая очередность заказов, или можете передвигать строчки в deals для максимальности продаж?

Например, у вас 100 свечек. Вчера вы договорились продать одну, а сегодня кто-то хочет купить все сто. Вы хотите посчитать доход от одной свечки, или от ста (передвинув вчерашнего покупателя в очереди)?
...
Рейтинг: 0 / 0
Можно ли реализовать задачу без условных операторов и циклов?
    #40005303
арт2010
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
НеофитSQL, немного другое
Есть таблица

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
CREATE TABLE Deals(id INT PRIMARY KEY CLUSTERED, 
date_deal DATETIME, 
client VARCHAR(20), 
product VARCHAR(20), 
qty DECIMAL(19,2), 
price DECIMAL(19,7)) 

INSERT dbo.Deals (id, date_deal, client, product, qty, price)
VALUES (1, '20190101', 'ivanov', 'LKOH', 10, 2000),
       (2, '20190102', 'ivanov', 'LKOH', 10, 2100), 
       (3, '20190102', 'ivanov', 'LKOH', 15, 2150), 
       (4, '20190103', 'ivanov', 'LKOH', -20, 2200), 
       (5, '20190104', 'ivanov', 'LKOH', -20, 2300),

       (6, '20190102', 'ivanov', 'GAZP', 100, 100),
       (7, '20190103', 'ivanov', 'GAZP', 200, 110),
       (8, '20190104', 'ivanov', 'GAZP', -50, 100),
       (9, '20190105', 'ivanov', 'GAZP', -50, 90),
       (10, '20190106', 'ivanov', 'GAZP', -200, 120),
       (11, '20190107', 'ivanov', 'GAZP', 150, 110),
       (12, '20190108', 'ivanov', 'GAZP', -100, 115),

       (13, '20190101', 'petrov', 'LKOH', 20, 2000),
       (14, '20190102', 'petrov', 'LKOH', 20, 2100),
       (15, '20190103', 'petrov', 'LKOH', -30, 2200),
       (16, '20190104', 'petrov', 'LKOH', -5, 2300),
       (17, '20190104', 'petrov', 'LKOH', -2, 2350),
       (18, '20190105', 'petrov', 'LKOH', -3, 2400),
       (19, '20190106', 'petrov', 'LKOH', 5, 2000)--,
       --(20, '20190107', 'petrov', 'LKOH', -1, 2100)




Написал хранимку с курсором. Но выяснилось что нужно сделать без курсора, циклов и условных операторов, чисто средствами SQL


Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
CREATE PROCEDURE [dbo].[Procedure1]
AS
BEGIN
    
    DECLARE @date_deal DATETIME, @client VARCHAR(20), @product VARCHAR(20), @qty DECIMAL(19,2), @price DECIMAL(19,7), @sum_qty DECIMAL(19,2), @id INT 
    DECLARE @mult_qty_price DECIMAL(19,7),  @prev_client VARCHAR(20),  @prev_product VARCHAR(20), @prev_qty DECIMAL(19,2), @prev_price DECIMAL(19,7) 
    DECLARE @cur CURSOR, @profit DECIMAL(19,7)   	

    CREATE TABLE #Temp
    (
      id INT PRIMARY KEY CLUSTERED, 
      date_deal DATETIME, 
      client VARCHAR(20), 
      product VARCHAR(20), 
      profit DECIMAL(19,7)
    );
    
    SET @cur = CURSOR FOR
    SELECT id, date_deal, client, product, qty, price 
    FROM Deals d
    ORDER BY id, client, product	   
    FOR READ ONLY    
    
    SET @sum_qty = 0
    SET @mult_qty_price = 0
    OPEN @cur
    FETCH NEXT  
	FROM @cur INTO @id, @date_deal, @prev_client, @prev_product, @prev_qty, @prev_price 
	
	IF (@prev_qty > 0)
	   BEGIN
	     SET @sum_qty = @prev_qty      
	     SET @mult_qty_price = @prev_qty * @prev_price  
	   END  

    WHILE @@fetch_status = 0
      BEGIN
	  
	  FETCH NEXT  
	  FROM @cur INTO @id, @date_deal, @client, @product, @qty, @price  
	  
	  IF (@prev_qty > 0)
	  IF (@client = @prev_client) AND (@product = @prev_product)	  
	   BEGIN
	     IF (@qty > 0)
	        BEGIN  
	          SET @sum_qty = @sum_qty + @qty 
	          SET @mult_qty_price = @mult_qty_price + @qty * @price
	        END   
         ELSE
	       BEGIN	       
	         IF (@sum_qty != 0) 
	            SET @profit = (ABS(@qty) *  @price - @mult_qty_price / @sum_qty * ABS(@qty))
	         ELSE      
	            SET @profit = (ABS(@qty) *  @price - ABS(@qty) * @prev_price)	                                               
             INSERT INTO #Temp VALUES (@id, @date_deal, @client, @product, @profit)             
             SET @sum_qty = 0             
             SET @mult_qty_price = 0                
	       END 
	    END       
	   ELSE
	    BEGIN 
             SET @sum_qty = 0
             SET @mult_qty_price = 0
	    END	   
	  
   	  SET @prev_client = @client 
   	  SET @prev_product = @product
   	  SET @prev_qty = @qty
   	  SET @prev_price = @price  
   	  
   	  IF (@prev_qty > 0) AND (@sum_qty = 0) AND (@mult_qty_price = 0)
	   BEGIN
	     SET @sum_qty = @prev_qty      
	     SET @mult_qty_price = @prev_qty * @prev_price  
	   END  	  
 	  
   	  END

   	  SELECT * FROM #temp

      CLOSE @cur
      DEALLOCATE @cur 

END




Перелопатил кучу инфы, но так до сих пор и не понял - возможно ли это. То, что возможно без курсора - очевидно. Но вот возможно ли без циклов или условных операторов?
...
Рейтинг: 0 / 0
Можно ли реализовать задачу без условных операторов и циклов?
    #40005309
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
арт2010,

похоже на расчет нарастающего итога: https://www.sql.ru/faq/faq_topic.aspx?fid=125
...
Рейтинг: 0 / 0
Можно ли реализовать задачу без условных операторов и циклов?
    #40005312
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
арт2010,

Я прочитал процедуру, но не увидел сортировку по дате. Возможно, вам SQL подает эти строки в хронологическом порядке по умолчанию? Вряд ли на это можно полагаться, добавьте в строку "ORDER BY id, client, product" также ", date_deal".

Думаю, вам нужна функция SUM() OVER () - вот пример ее применения.
https://codingsight.com/calculating-running-total-with-over-clause-and-partition-by-clause-in-sql-server/

Сам будучи новичком, я ей до сегодняшнего дня не пользовался, но поигравшись немного, увидел что Оракл (моя среда) не позволяет ее использовать в WHERE или в HAVING, поэтому для своего примера я добавил колонку и обернул в селект.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
with students (id, name, age) as 
     (select 1, 'Alice', 10 from dual union all  -- "from dual" - требование Оракл на SQL заменяется на пробел
      select 2, 'Bob',   13 from dual union all
      select 3, 'Chuck', 11 from dual union all
      select 4, 'David', 12 from dual)
      
select name, age from 
    (select name, age, sum(age) over (order by id) as sumage 
       from students) t
 where t.sumage <= 30;



Этот запрос перечисляет студентов, пока суммарный возраст не превысит 30 - похоже на вашу задачу?

Если нужно только ответ (бегущая сумма, которая не превышает 30)
Код: sql
1.
2.
3.
4.
5.
select sumage from (      
    select sum(age) over (order by id) as sumage 
       from students
       order by sumage desc) t
 where t.sumage <= 30 and rownum=1



Я не берусь написать MsSQL без ошибок, но мне интересно попробовать:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
SELECT idb, clientb, productb, qty_buy,
  (SELECT Profit from
      (SELECT SUM (qty * price) Profit, SUM(qty) OVER (ORDER BY deal_date) RunQty 
         FROM dbo.Deals 
        WHERE (id < idb) AND (product = productb) AND (client = clientb) AND (qty > 0) 
        ORDER BY RunQty DESC) t
    WHERE t.RunQty <= qty_buy and ROWNUM=1)) -- вроде в MSSQL можно "TOP 1"
  FROM #buy b
 ORDER BY idb
...
Рейтинг: 0 / 0
Можно ли реализовать задачу без условных операторов и циклов?
    #40005320
арт2010
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
НеофитSQL, благодарю за помощь, завтра уже буду детально разбирать, но запрос в sql не сработал, в смысле, ошибки, попробую модернизировать
...
Рейтинг: 0 / 0
Можно ли реализовать задачу без условных операторов и циклов?
    #40005321
арт2010
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владислав Колосов, благодарю, попробую приспособить к своей задаче
...
Рейтинг: 0 / 0
Можно ли реализовать задачу без условных операторов и циклов?
    #40005330
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как-то так
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
with rt(product, client, qty, profit) as
(
 select
  product, client,
  sum(qty) over (partition by product, client order by id),
  sum(qty * price) over (partition by product, client order by id)
 from
  dbo.Deals
)
select
 b.idb, b.clientb, b.productb, b.qty_buy, p.profit
from
 #buy b outer apply
 (select top (1) profit from rt where product = b.productb and client = b.clientb and qty <= b.qty_buy order by qty desc) p;
...
Рейтинг: 0 / 0
Можно ли реализовать задачу без условных операторов и циклов?
    #40005577
арт2010
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm, огромное спасибо, натолкнули на мысль, мне нужно было примерно следующее

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
  SELECT
   ids, product, client,(ABS(qtys) * prices - (CASE WHEN (sum_qty - qty) > 0 THEN sum_profit/sum_qty ELSE price END) *  ABS(qtys)) profit
    FROM 
     (SELECT id ids, client clients, product products, qty qtys, price prices, 
	         (SELECT SUM(qty) sum_buy FROM dbo.Deals d2 WHERE (id < d.id) AND (client = d.client) AND (product = d.product)) qty_buy
          FROM dbo.Deals d 
          WHERE (qty < 0)) s  
	
	INNER JOIN
	
      (SELECT id, qty, price, product, client, SUM(qty) OVER (PARTITION BY product, client ORDER BY id) sum_qty,
              SUM(qty * price) OVER (PARTITION BY product, client ORDER BY id) sum_profit
       FROM dbo.Deals) bs 

    ON bs.id = s.ids - 1
    ORDER BY s.ids




Но тут один затык, мне нужен синтаксис не выше 2008, а там order by не допустимо в over. Как бы мне обойти это?
...
Рейтинг: 0 / 0
Можно ли реализовать задачу без условных операторов и циклов?
    #40005578
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
арт2010,

вы чего то путаете, оконки сразу как появились c 2005 были с order by

вот Вам ссылка на документацию к 2008
https://docs.microsoft.com/ru-ru/previous-versions/sql/sql-server-2008/ms189461(v=sql.100)


а вот к 2005
https://docs.microsoft.com/ru-ru/previous-versions/sql/sql-server-2005/ms189461(v=sql.90)
...
Рейтинг: 0 / 0
Можно ли реализовать задачу без условных операторов и циклов?
    #40005602
арт2010
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
felix_ff, тем не менее в 2014 все ок, а в 2008 - ругается на order и курение инета подтвердило это
...
Рейтинг: 0 / 0
Можно ли реализовать задачу без условных операторов и циклов?
    #40005605
арт2010
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А вообще у меня работает все таки не совсем так как мне надо. Если перед продажей были только покупки, то все правильно работает. Но вот если были перед продажей не только покупки, но и другие продажи, надо уже считать не сумму произведений, деленную на оставшиеся акции, а как бы обнулять некоторые продажи полностью или частично, исходя из условия, что первыми продаются самые первые купленные акции. То есть например для id = 5, на предыдущем шаге id = 4 продали 20 штук, то есть id = 1 (10 акций) и id = 2 (10 акций) обнуляюся и в расчетах не участвуют. То есть для id = 5 учитываем только покупку при id = 3:
profit = 20 * 2300 - (15 * 2150) / 15 * 20 = 3000

Причем "обнуляться могут продажи и частично" - это хорошо видно на примере id = 16
При id = 15 продали 30 штук - то есть они "обнуляют" 20 штук купленных при id = 13 и 10 штук купленных
при id = 14, то есть в расчете участвует только покупка 10 штук при id = 14: profit = * 2300 - (10 * 2100) / 10 * 5

То есть получается хоть как нужен цикл с предусловием внутри этого запроса?
Либо я просто не могу отбросить шоры процедурного мышления и понять как это сделать без циклов и ветвлений (если это вообще возможно???), помогите пожалуйста!


Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
(1, '20190101', 'ivanov', 'LKOH', 10, 2000),
       (2, '20190102', 'ivanov', 'LKOH', 10, 2100), 
       (3, '20190102', 'ivanov', 'LKOH', 15, 2150), 
       (4, '20190103', 'ivanov', 'LKOH', -20, 2200),  profit = 2142,8571428571
       (5, '20190104', 'ivanov', 'LKOH', -20, 2300),  
--сейчас при id=5 profit = 0 * 2300 - (10*2000 + 10*2100 + 15 * 2150 - 20 * 2200) / 15 * 20 = 7000, 
-- а должно profit = 20 * 2300 - (15 * 2150) / 15 * 20 = 3000  

       (6, '20190102', 'ivanov', 'GAZP', 100, 100),
       (7, '20190103', 'ivanov', 'GAZP', 200, 110),
       (8, '20190104', 'ivanov', 'GAZP', -50, 100),
       (9, '20190105', 'ivanov', 'GAZP', -50, 90),
       (10, '20190106', 'ivanov', 'GAZP', -200, 120),
       (11, '20190107', 'ivanov', 'GAZP', 150, 110),
       (12, '20190108', 'ivanov', 'GAZP', -100, 115),
-- id=12 В расчёте учитывается только покупка id=11, т.к. всё что ранее было куплено уже продано и на доход по этой сделке не --влияет profit = 100*115р - 100*110р = 500

       (13, '20190101', 'petrov', 'LKOH', 20, 2000),
       (14, '20190102', 'petrov', 'LKOH', 20, 2100),
       (15, '20190103', 'petrov', 'LKOH', -30, 2200), profit = 30 * 2200 - (20 * 2000 + 20 * 2100) / 40 * 30 = 4500
       (16, '20190104', 'petrov', 'LKOH', -5, 2300),
-- сейчас при id = 16 profit = 5 * 2300 - (20 * 2000 + 20 * 2100 - 30 * 2200) / 10 * 5 = 3500
-- нужно  при id = 16 profit = * 2300 - (10 * 2100) / 10 * 5
       (17, '20190104', 'petrov', 'LKOH', -2, 2350),
       (18, '20190105', 'petrov', 'LKOH', -3, 2400),
       (19, '20190106', 'petrov', 'LKOH', 5, 2000)





Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
SELECT
   ids, product, client,(ABS(qtys) * prices - (CASE WHEN (sum_qty - qty) > 0 THEN sum_profit/sum_qty ELSE price END) *  ABS(qtys)) profit
    FROM 
     (SELECT id ids, client clients, product products, qty qtys, price prices, 
	         (SELECT SUM(qty) sum_buy FROM dbo.Deals d2 WHERE (id < d.id) AND (client = d.client) AND (product = d.product)) qty_buy
          FROM dbo.Deals d 
          WHERE (qty < 0)) s  
	
	INNER JOIN
	
      (SELECT id, qty, price, product, client, SUM(qty) OVER (PARTITION BY product, client ORDER BY id) sum_qty,
              SUM(qty * price) OVER (PARTITION BY product, client ORDER BY id) sum_profit
       FROM dbo.Deals) bs 

    ON bs.id = s.ids - 1
    ORDER BY s.ids





Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
CREATE TABLE Deals(id INT PRIMARY KEY CLUSTERED, 
date_deal DATETIME, 
client VARCHAR(20), 
product VARCHAR(20), 
qty DECIMAL(19,2), 
price DECIMAL(19,7)) 

INSERT dbo.Deals (id, date_deal, client, product, qty, price)
VALUES (1, '20190101', 'ivanov', 'LKOH', 10, 2000),
       (2, '20190102', 'ivanov', 'LKOH', 10, 2100), 
       (3, '20190102', 'ivanov', 'LKOH', 15, 2150), 
       (4, '20190103', 'ivanov', 'LKOH', -20, 2200), 
       (5, '20190104', 'ivanov', 'LKOH', -20, 2300),

       (6, '20190102', 'ivanov', 'GAZP', 100, 100),
       (7, '20190103', 'ivanov', 'GAZP', 200, 110),
       (8, '20190104', 'ivanov', 'GAZP', -50, 100),
       (9, '20190105', 'ivanov', 'GAZP', -50, 90),
       (10, '20190106', 'ivanov', 'GAZP', -200, 120),
       (11, '20190107', 'ivanov', 'GAZP', 150, 110),
       (12, '20190108', 'ivanov', 'GAZP', -100, 115),

       (13, '20190101', 'petrov', 'LKOH', 20, 2000),
       (14, '20190102', 'petrov', 'LKOH', 20, 2100),
       (15, '20190103', 'petrov', 'LKOH', -30, 2200),
       (16, '20190104', 'petrov', 'LKOH', -5, 2300),
       (17, '20190104', 'petrov', 'LKOH', -2, 2350),
       (18, '20190105', 'petrov', 'LKOH', -3, 2400),
       (19, '20190106', 'petrov', 'LKOH', 5, 2000)


...
Рейтинг: 0 / 0
Можно ли реализовать задачу без условных операторов и циклов?
    #40005611
Фотография Ennor Tiegael
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
felix_ff,

OVER() сам по себе - да, позволял ORDER BY с 2005, но только с ранжирующими функциями. Для обычных агрегаток типа sum / count поддержка over(order by) появилась только в 2012.

ТС,

Идите в форумный FAQ и смотрите, как сделать нарастающий итог на версиях до 2012. Там все будет медленно и печально.
...
Рейтинг: 0 / 0
Можно ли реализовать задачу без условных операторов и циклов?
    #40005618
арт2010
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ennor Tiegael, у меня не нарастающий итог. Точнее не только он. Мне нужно аналог цикла с предусловием средствами SQL. То есть я вычислил некое суммарное количество купленных qty и проданных qty на определенном id. Дальше мне нужно вернуться на начальный id в рамках данного продукта и клиента и снова цикл: если текущий qty > 0 и сумма проданных qty - (сумма qty > 0 с начала и до текущего qty, включая его самого) > 0 тогда отбрасываем иначе sum_qty := sum_qty + qty(id) * price(id). Когда дошли до нужного id, считаем по формуле, причем sum_qty берется с предыдущего шага, а текущие qty и price - с текущего
И так по всем группировкам продукт/клиент. Короче сложное условие, только отдаленно похожее на нарастающую сумму
Вот я и пытаюсь понять самое главное - возможно ли это сделать чисто средствами SQL (+ временные таблицы), без использования if-else, while, функций, курсоров и прочих процедурных инструментов. Есть возможно, то есть смысл двигаться дальше в этом направлении иначе нет.
...
Рейтинг: 0 / 0
Можно ли реализовать задачу без условных операторов и циклов?
    #40005653
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
арт2010,

сократите количество терминов до "приход" и "расход" и посмотрите,как можно сформулировать задачу без "акция", "обнуляют" и так далее. Мне , например, плохо понятно, много избыточной информации и перекрёстных ссылок в изложении.
...
Рейтинг: 0 / 0
Можно ли реализовать задачу без условных операторов и циклов?
    #40005693
арт2010
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владислав Колосов, уже приводил пример по цифрам, на конкретных цифрах гораздо понятнее, чем словами

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
(1, '20190101', 'ivanov', 'LKOH', 10, 2000),
       (2, '20190102', 'ivanov', 'LKOH', 10, 2100), 
       (3, '20190102', 'ivanov', 'LKOH', 15, 2150), 
       (4, '20190103', 'ivanov', 'LKOH', -20, 2200),  profit = 2142,8571428571
       (5, '20190104', 'ivanov', 'LKOH', -20, 2300),  
--сейчас при id=5 profit = 0 * 2300 - (10*2000 + 10*2100 + 15 * 2150 - 20 * 2200) / 15 * 20 = 7000, 
-- а должно profit = 20 * 2300 - (15 * 2150) / 15 * 20 = 3000  

       (6, '20190102', 'ivanov', 'GAZP', 100, 100),
       (7, '20190103', 'ivanov', 'GAZP', 200, 110),
       (8, '20190104', 'ivanov', 'GAZP', -50, 100),
       (9, '20190105', 'ivanov', 'GAZP', -50, 90),
       (10, '20190106', 'ivanov', 'GAZP', -200, 120),
       (11, '20190107', 'ivanov', 'GAZP', 150, 110),
       (12, '20190108', 'ivanov', 'GAZP', -100, 115),
-- id=12 В расчёте учитывается только покупка id=11, т.к. всё что ранее было куплено уже продано и на доход по этой сделке не --влияет profit = 100*115р - 100*110р = 500

       (13, '20190101', 'petrov', 'LKOH', 20, 2000),
       (14, '20190102', 'petrov', 'LKOH', 20, 2100),
       (15, '20190103', 'petrov', 'LKOH', -30, 2200), profit = 30 * 2200 - (20 * 2000 + 20 * 2100) / 40 * 30 = 4500
       (16, '20190104', 'petrov', 'LKOH', -5, 2300),
-- сейчас при id = 16 profit = 5 * 2300 - (20 * 2000 + 20 * 2100 - 30 * 2200) / 10 * 5 = 3500
-- нужно  при id = 16 profit = * 2300 - (10 * 2100) / 10 * 5
       (17, '20190104', 'petrov', 'LKOH', -2, 2350),
       (18, '20190105', 'petrov', 'LKOH', -3, 2400),
       (19, '20190106', 'petrov', 'LKOH', 5, 2000)


...
Рейтинг: 0 / 0
Можно ли реализовать задачу без условных операторов и циклов?
    #40005696
mnbvcx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ennor Tiegael

...Для обычных агрегаток типа sum / count поддержка over(order by) появилась только в 2012.


Не в 2008R2 ?
...
Рейтинг: 0 / 0
Можно ли реализовать задачу без условных операторов и циклов?
    #40005770
Фотография Ennor Tiegael
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mnbvcx
Ennor Tiegael

...Для обычных агрегаток типа sum / count поддержка over(order by) появилась только в 2012.


Не в 2008R2 ?
Насколько мне врет моя память, в 2012. Но проверить не могу, негде (по счастью ).
...
Рейтинг: 0 / 0
Можно ли реализовать задачу без условных операторов и циклов?
    #40006454
арт2010
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Апну тему, может кто-нибудь таки подскажет в каком направлении двигаться, напомню это не просто нарастащий итог. Решил попробовать рекурсией, но столкнулся что не могу сделать вложенную рекурсию вида
with bla-bla(id, ....)
select id, ..., (with ... sum(qty)...)
то есть не могу в значение поля первой рекурсии подставить результат второй рекурсии, хотя там sum и точно не будет multiple rows - sql ругается. так можно делать вложенную рекурсию и если да, то как?
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Можно ли реализовать задачу без условных операторов и циклов?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]