【问题标题】:Simplify Multiple Join SQL Column简化多连接 SQL 列
【发布时间】:2013-11-25 16:44:52
【问题描述】:

我有带有连接语句的选择语句查询,我用它来从加入表中获取价值

这是我的选择查询:

select 
case when p1.Value2 is not null then p1.Value3 end as fix1,
case when p1.Value2 is not null then p2.Value3 end as fix2,
case when p1.Value2 is not null then p3.Value3 end as fix3,
case when p1.Value2 is not null then p4.Value3 end as fix4,
case when p1.Value2 is not null then p5.Value3 end as fix5,
case when p1.Value2 is not null then p6.Value3 end as fix6
from tc t
left join (select * from  Parameter where paramtype='fix') as p1 on p1.Value2 = t.FIX 
left join (select * from  Parameter where paramtype='fix') as p2 on p2.Value2 = t.FIX1
left join (select * from  Parameter where paramtype='fix') as p3 on p3.Value2 = t.FIX2
left join (select * from  Parameter where paramtype='fix') as p4 on p4.Value2 = t.FIX3
left join (select * from  Parameter where paramtype='fix') as p5 on p5.Value2 = t.FIX4
left join (select * from  Parameter where paramtype='fix') as p6 on p6.Value2 = t.FIX5
where CUST_ACCT ='10053996'

我认为它很复杂,所以我像这样更改我的代码:

select 
fix +' '+(select Value3 from Parameter where ParamType = 'fix' and Value2 = fix) as fix,
FIX1 +' '+(select Value3 from Parameter where ParamType = 'fix' and Value2 = FIX1) as FIX1,
FIX2 +' '+(select Value3 from Parameter where ParamType = 'fix' and Value2 = FIX2) as FIX2,
FIX3 +' '+(select Value3 from Parameter where ParamType = 'fix' and Value2 = FIX3) as FIX3,
FIX4 +' '+(select Value3 from Parameter where ParamType = 'fix' and Value2 = FIX4) as FIX4,
FIX5 +' '+(select Value3 from Parameter where ParamType = 'fix' and Value2 = FIX5) as FIX5
from tc where CUST_ACCT ='10053996'

是否可以简化我的代码?或者如果我想做这样的事情,我应该创建这样的选择语句?

【问题讨论】:

  • 您如何尝试通过查询来解释您想要实现的目标
  • 其实我想要更简单有效的代码,也想避免子查询出错

标签: sql sql-server join


【解决方案1】:

这样的解决方案怎么样?

SELECT /*extra fields from tc ==>>*/ x, y /*<<==*/
    , FIX, FIX1, FIX2, FIX3, FIX4, FIX5
FROM (
    SELECT fields, P.Value3, /*extra fields from tc ==>>*/ x, y /*<<==*/
    FROM (
        SELECT *
        FROM tc
        WHERE CUST_ACCT ='10053996'
    ) T
    UNPIVOT (
        unpvt FOR fields in (FIX,FIX1,FIX2,FIX3,FIX4,FIX5)
    ) UPV
    LEFT JOIN Parameter P ON P.paramtype='fix' AND P.Value2 = UPV.unpvt
) T
PIVOT (
    MIN(Value3) FOR fields in (FIX,FIX1,FIX2,FIX3,FIX4,FIX5)
) AS PV

【讨论】:

  • 只是好奇,这个代码如何显示所有的TC字段?不熟悉枢轴非枢轴的东西
  • 哦,明白了,所以我们应该先声明所有字段,然后再调用它们
【解决方案2】:

您可以在第一条语句中将Case 语句替换为IsNull(expression, valueIfNull)

我有带有连接语句的选择语句查询,我用它来从加入表中获取价值

这是我的选择查询:

select 
IsNull(p1.Value2 ,p1.Value3) as fix1,
IsNull(p1.Value2 ,p1.Value3) as fix2,
IsNull(p1.Value2 ,p1.Value3) as fix3,
IsNull(p1.Value2 ,p1.Value3) as fix4,
IsNull(p1.Value2 ,p1.Value3) as fix5,
IsNull(p1.Value2 ,p1.Value3) as fix6,
from tc t
left join (select * from  Parameter where paramtype='fix') as p1 on p1.Value2 = t.FIX 
left join (select * from  Parameter where paramtype='fix') as p2 on p2.Value2 = t.FIX1
left join (select * from  Parameter where paramtype='fix') as p3 on p3.Value2 = t.FIX2
left join (select * from  Parameter where paramtype='fix') as p4 on p4.Value2 = t.FIX3
left join (select * from  Parameter where paramtype='fix') as p5 on p5.Value2 = t.FIX4
left join (select * from  Parameter where paramtype='fix') as p6 on p6.Value2 = t.FIX5
where CUST_ACCT ='10053996'

【讨论】:

  • 啊哈,看起来更简单了,但是还需要6个left join语句吗?
  • 是的,但是连接比子查询好。 select 语句中的子查询针对每一行执行,而 join 查询针对 one 执行
  • 是的,我已经尝试了一些场景,我发现子查询可能会出错,因为如果找到超过 1 个值,它会抛出错误
  • case when p1.Value2 is not null then p1.Value3 endIsNull(p1.Value2, p1.Value3) 给出完全不同的结果。在第二种情况下,如果p1.Value2 is null,您将得到p1.Value3,而在第一种情况下,我们有相反的条件。此外,第一个子句永远不会返回p1.Value2,但第二个子句会。
【解决方案3】:

您绝对不需要多次加入同一张桌子。这是避免它的简单技巧:

select 
case when pt.f = 1 then pt.Value3 end as fix1,
case when pt.f2 = 1 then pt.Value3 end as fix2,
... 
from tc
left join (select 
      CASE WHEN p.Value2 = t.FIX THEN 1 ELSE 0 END AS f, 
      CASE WHEN p.Value2 = t.FIX1 THEN 1 ELSE 0 END AS f1, 
      CASE WHEN p.Value2 = t.FIX2 THEN 1 ELSE 0 END AS f2, 
      CASE WHEN p.Value2 = t.FIX3 THEN 1 ELSE 0 END AS f3, 
      CASE WHEN p.Value2 = t.FIX4 THEN 1 ELSE 0 END AS f4, 
      CASE WHEN p.Value2 = t.FIX5 THEN 1 ELSE 0 END AS f5
    from  Parameter AS p where paramtype = 'fix') AS pt
    ON pt.Value2 IN (tc.FIX, tc.FIX2, tc.FIX3, tc.FIX4, tc.FIX5)
where CUST_ACCT ='10053996'

也许你可以根据你的具体情况简化JOIN-conditions。这个想法是引入参数而不是多个连接。

【讨论】:

    【解决方案4】:

    怎么样:

    select
    case when p1.Value2 is not null then p1.Value3 end as fix1,
    case when p1.Value2 is not null then p2.Value3 end as fix2, 
    case when p1.Value2 is not null then p3.Value3 end as fix3, 
    case when p1.Value2 is not null then p4.Value3 end as fix4, 
    case when p1.Value2 is not null then p5.Value3 end as fix5, 
    case when p1.Value2 is not null then p6.Value3 end as fix6 
    from tc t 
    left join Parameter as p1 
    on p1.Value2 = t.FIX  AND p1.paramtype='fix'  
    left join Parameter as p2 
    on p2.Value2 = t.FIX1 AND p2.paramtype='fix'  
    left join Parameter as p3
    on p3.Value2 = t.FIX2 AND p3.paramtype='fix' 
    left join Parameter as p4
    on p4.Value2 = t.FIX3 AND p4.paramtype='fix' 
    left join Parameter as p5
    on p5.Value2 = t.FIX4 AND p5.paramtype='fix' 
    left join Parameter as p6
    on p6.Value2 = t.FIX5 AND p6.paramtype='fix' 
    where CUST_ACCT ='10053996'
    

    【讨论】:

      猜你喜欢
      • 2018-10-30
      • 1970-01-01
      • 2018-02-03
      • 1970-01-01
      • 1970-01-01
      • 2017-04-24
      • 1970-01-01
      • 2017-02-07
      • 1970-01-01
      相关资源
      最近更新 更多