【问题标题】:SQL select rows with different values in two columnSQL在两列中选择具有不同值的行
【发布时间】:2020-03-27 09:14:21
【问题描述】:

我有 4-5 个表的数据库。 我正在收集这样的数据

N |名称_ |索尼_ |萨夫多 |福伊达 | Val(货币) 1 |苹果 | 5公斤 | 5000 | 500 |乌兹别克斯坦 2 |香蕉| 4公斤 | 7000 | 800 |乌兹别克斯坦 3 |桃子 | 2公斤 | 2 | 0.2 |美元

我想将 Currency 列分开,如下所示

N |名称_ |索尼_ |萨夫多 |福伊达 | VAL1 | VAL2 1 |苹果 | 5公斤 | 5000 | 500 |乌兹别克斯坦 | 2 |香蕉| 4公斤 | 7000 | 800 |乌兹别克斯坦 | 3 |桃子 | 2公斤 | 2 | 0.2 | |美元

这是我的 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 

【问题讨论】:

    标签: sql sqlite multiple-columns


    【解决方案1】:

    我会将子查询移至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 的子查询,但这将是另一个问题。

    【讨论】:

    【解决方案2】:

    将您的查询放在 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 连接更改为 tsfinner 连接。如果结果是你所期望的,那很好。如果不将这些条件移至 ON 子句。

    此外,如果关系是 1:1,则可以使用 joins,而不是您在选择列表中使用的所有 select 语句。
    试试这个:

    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
    

    【讨论】:

    • 感谢forpas 的关注和花费时间。你的版本也很完美。
    • @HayrullaMelibayev 不要在选择列表中使用子查询。这是您在表之间进行连接的地方,这就是 sql 中存在连接的原因。当你混合子查询和连接时,你的代码很难维护。
    最近更新 更多