Мне нужен запрос, чтобы получить вывод из данной таблицы - PullRequest
0 голосов
/ 24 августа 2018

Положение таблицы, как показано ниже.

CREATE TABLE position (
tran_Date date,
clientid varchar(255),
stock varchar(255),
quantity number
);

insert into position values ('23-AUG-2018','Client1','Infosys',100);
insert into position values ('23-AUG-2018','Client1','Wipro',200);
insert into position values ('23-AUG-2018','Client1','TechM',150);
insert into position values ('23-AUG-2018','Client2','IBM',100);
insert into position values ('24-AUG-2018','Client1','Infosys',150);
insert into position values ('24-AUG-2018','Client1','Wipro',150);
insert into position values ('24-AUG-2018','Client2','IBM',100);

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

ClientID, 
Stock, 
ChangeInQty(a calculative bucket which will hold the diff of qty between 2 dates),
classification(a calculative bucket on changeinqty. 
    IF changeinqty in '-'(negative) 'shares taken down'
    if changeinqty in '+'(positive) 'shares taken up'
    if changeinqty in '0'(no change) 'shares remain same'
    if changeinqty is indeterminable 'shares position removed')

Мой подход был таким.

Select clientid,stock,changeinqty, 
case 
when x.changeinqty >0 then 'Taken Up'
when x.changeinqty <0 then 'Taken Down'
when x.changeinqty =0 then 'Same'
when x.changeinqty is null then 'Removed'
end as classification
From (select a.clientid,a.stock,a.quantity-b.quantity as changeinqty from
(Select tran_date,clientid,stock,quantity from position where tran_date='23-Aug-2018')  a left join
(Select tran_date,clientid,stock,quantity from position where tran_date='24-Aug-2018')  b
on a.clientid=b.clientid and a.stock=b.stock) x;

Ответы [ 4 ]

0 голосов
/ 24 августа 2018

Вы включаете жестко закодированные даты в свой скрипт. Это работает для ваших образцов данных, но не удастся, если в датах есть пробелы. Следующий скрипт сканирует предыдущие позиции и сравнивает текущую позицию строки с последней позицией. Это должно работать для любых данных и любой даты:

select *, (p.quantity - prevP.quantity) as change
from dbo.position p
left outer join dbo.position prevP
on p.clientid = prevP.clientid
    and p.stock = prevP.stock
    and prevP.tran_Date = (select max(allPrevP.tran_Date)
                            from dbo.position allPrevP
                            where allPrevP.clientid = prevP.clientid
                                and allPrevP.stock = p.stock
                                and allPrevP.tran_Date < p.tran_Date
                            group by allPrevP.clientid, allPrevP.stock)
order by p.clientid, p.stock, p.tran_Date
0 голосов
/ 24 августа 2018

Я бы сконцентрировал это примерно так:

select day1.clientid
     , day1.stock
     , day1.quantity - day2.quantity as changeinqty
     , case sign(day1.quantity - day2.quantity)
           when 1 then 'Up'
           when -1 then 'Down'
           when 0 then 'Unchanged'
           else 'Removed'
       end as classification
from   demo_position day1
       left join demo_position day2
            on  day2.clientid = day1.clientid
            and day2.stock = day1.stock
            and day2.tran_date = day1.tran_date +1
where  day1.tran_date = date '2018-08-23';

Я предполагаю (возможно, ошибочно), что отчет сравнивает один день со следующим, поэтому я заменил более жестко закодированную дату на day1.tran_date +1.

(Только что видел ответ Гордона, который повторяется по тому же принципу. Как он упоминает в своем ответе, похоже, что day1.quantity - day2.quantity на самом деле должно быть day2.quantity - day1.quantity, чтобы соответствовать меткам вверх / вниз / без изменений. Я был на этом, потому что takedown и takeup не похоже на то, что вы имели в виду.)

0 голосов
/ 24 августа 2018

Вот альтернативный способ поиска

select clientid,
stock, 
quantity,
a.change_stock,
case when a.change_stock < 0 THEN  'shares taken down' 
when a.change_stock > 0 THEN  'shares taken up'
when a.change_stock = 0 THEN  'shares remain same' end classification from (
Select clientid,stock, quantity,  lead(quantity,1,0) over ( partition by clientid,stock order by tran_Date asc) - quantity change_stock 
from position ) a
where a.quantity + a.change_stock <> 0
union all
select clientid, -- query to take non-duplicate row
stock, 
quantity,null,'shares position removed' from (select clientid,
stock, 
quantity , count(*) over (partition by clientid,stock) cnt from position )a where a.cnt=1;

Здесь комбинированный запрос с дубликатами и без дубликатов без объединения всех

select clientid,
stock, 
quantity,
case when a.cnt=1 THEN NULL ELSE a.change_stock END change_stock,
case when a.change_stock < 0 and a.cnt > 1 THEN  'shares taken down' 
when a.change_stock > 0 and a.cnt > 1 THEN  'shares taken up'
when a.change_stock = 0 and a.cnt > 1 THEN  'shares remain same' 
when a.cnt=1 THEN 'shares position removed' end classification from (
Select clientid,stock, quantity,  lead(quantity,1,0) over ( partition by clientid,stock order by tran_Date asc) - quantity change_stock ,count(*) over (partition by clientid,stock) cnt
from position ) a
where a.quantity + a.change_stock <> 0 or cnt=1;
0 голосов
/ 24 августа 2018

Ваш запрос выглядит хорошо, но я бы упростил его до:

Select p1.clientid, p1.stock, (p2.quantity - p1.quantity) as changeinqty, 
       (case when p2.quantity is null then 'Removed'
             when p2.quantity > p1.quantity then 'Taken Up'
             when p2.quantity < p1.quantity then 'Taken Down'
             when p2.quantity = p1.quantity then 'Same'
        end) as classification
From position p1 left join
     position p2
     on p1.client_id = p2.client_id and
        p1.stock = p2.stock and
        p2.tran_date = date '2018-08-24'
where p1.tran_date = date '2018-08-23;

Примечания:

  • Условие для первой даты содержится в предложении where, поэтому этирассматриваются только позиции.
  • Условие для второй даты содержится в предложении on, поэтому включены все строки с первой даты, даже те, которые отсутствуют.
  • Я думаю, чтологика для вашего кода обратная.Это более прозрачно.
  • Oracle поддерживает ключевое слово date, поэтому вы можете использовать стандартные форматы ISO / ANSI для дат.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...