SQL выбрать строки с разными значениями в двух столбцах - PullRequest
1 голос
/ 27 марта 2020

У меня есть база данных с 4-5 таблицами. Я собираю данные, подобные этому

N | Nom_  | Soni_  | Savdo  | Foyda  | Val(Currency)
1 | Apple |    5kg | 5000   |   500  | UZS
2 | Banana|    4kg | 7000   |   800  | UZS
3 | Peach |    2kg | 2      |   0.2  | USD

И я хочу разделить столбец Валюта на два столбца, как показано ниже

N | Nom_  | Soni_  | Savdo  | Foyda  | Val1  |  Val2
1 | Apple |    5kg | 5000   |   500  | UZS   |
2 | Banana|    4kg | 7000   |   800  | UZS   |
3 | Peach |    2kg | 2      |   0.2  |       |   USD

Вот мой код SQL.

select  s.nom_ , sum(o.soni_) as soni_ ,
   sum(o.soni_*(select narx_ from toper where id_=o.id_ )) as savdo_, 
   sum((o.soni_*o.narx_-o.soni_* (select narx_ from toper where id_=o.id_op ))) as foyda_,
   (select nom_ from tsinf where id_=o.id_v) as val_ 
      from toper o left join tsf f on o.id_sf=f.id_  
      left join tsinf s on o.id_s=s.id_  
where (f.date_>=date('2020-01-01')) and (f.date_<=date('2020-04-04')) 
and f.oper_=-1  group by id_s, id_v 

Ответы [ 2 ]

1 голос
/ 27 марта 2020

Я бы переместил подзапрос в предложение FROM (используя LEFT JOIN). Тогда разделение - это просто два CASE выражения:

select s.nom_ , sum(o.soni_) as soni_,
       sum(o.soni_*(select narx_ from toper where id_=o.id_ )) as savdo_, 
       sum((o.soni_*o.narx_-o.soni_* (select narx_ from toper where id_=o.id_op ))) as foyda_,
        (case when sv.nom_1 = 'UZS' then sv.nom_1 end) as uzs,
        (case when sv.nom_1 = 'USD' then sv.nom_1 end) as usd
from toper o left join
     tsf f
     on o.id_sf = f.id_  left join
     tsinf s
     on o.id_s = s.id_ left join
     tsinf sv
     on sv.id_ = o.id_v
where f.date_ >= date('2020-01-01') and
      f.date_ <= date('2020-04-04') and 
      f.oper_ = -1 
group by id_s, id_v ;

Я бы также рекомендовал удалить подзапросы до toper, но это был бы другой вопрос.

1 голос
/ 27 марта 2020

Поместите ваш запрос в CTE и затем используйте выражение CASE, чтобы выбрать 2 столбца:

with cte as (
  select s.nom_ , sum(o.soni_) as soni_ ,
    sum(o.soni_*(select narx_ from toper where id_=o.id_ )) as savdo_, 
    sum((o.soni_*o.narx_-o.soni_* (select narx_ from toper where id_=o.id_op ))) as foyda_,
    (select nom_ from tsinf where id_=o.id_v) as val_ 
  from toper o left join tsf f on o.id_sf=f.id_  
  left join tsinf s on o.id_s=s.id_  
  where (f.date_>=date('2020-01-01')) and (f.date_<=date('2020-04-04')) 
  and f.oper_=-1  
  group by id_s, id_v
)
select nom_, soni, savdo, foyda_, 
  case when val_ = 'UZS' then val_ end as Val1,
  case when val_ = 'USD' then val_ end as Val2 
from cte

Но вы должны знать, что условие:

where (f.date_>=date('2020-01-01')) and (f.date_<=date('2020-04-04'))

изменяет ваше left объединение на tsf на inner присоединение. Если результаты того, что вы ожидаете, то хорошо. Если нет, переместите эти условия в предложение ON. Также вместо всех операторов select, которые вы используете в списке выбора, вы можете использовать joins, если отношения 1: 1. Попробуйте это:

select  
  s.nom_, 
  sum(o.soni_) as soni_,
  sum(o.soni_* o2.narx_) as savdo_, 
  sum((o.soni_*o.narx_-o.soni_* o3.narx_) as foyda_,
  case when s2.nom_ = 'UZS' then s2.nom_ end as Val1,
  case when s2.nom_ = 'USD' then s2.nom_ end as Val2 
from toper o 
left join toper o2 on o2.id_=o.id_
left join toper o3 on o3.id_=o.id_op
left join tsf f on o.id_sf=f.id_  
left join tsinf s on o.id_s=s.id_ 
left join tsinf s2 on o.id_v=s2.id_  
where (f.date_>=date('2020-01-01')) and (f.date_<=date('2020-04-04')) and f.oper_=-1  
group by id_s, id_v
...