【问题标题】:How to merge to rows into a single row in SQL Server如何在 SQL Server 中将行合并为单行
【发布时间】:2018-05-03 05:33:37
【问题描述】:

我有一个执行联合操作的查询。这是查询

SELECT R.ThanaID, R.RoadTypeId, Count(R.Id) AS NoRdExist, 0 AS NoRdImp, 0 AS 
BcLenExist, 0 AS BcLenImp FROM RoadInventory AS R 
        INNER JOIN Thana AS A ON R.ThanaID = A.Id GROUP BY R.ThanaID,R.RoadTypeId 

UNION SELECT R.ThanaID, R.RoadTypeId, 0 AS NoRdExist, Count(R.Id) AS 
NoRdImp,0 AS BcLenExist, 0 AS BcLenImp FROM RoadInventory_Temp AS R
        INNER JOIN Thana AS A ON R.ThanaID = A.Id GROUP BY R.ThanaID, R.RoadTypeId 

UNION SELECT R.ThanaID, RI.RoadTypeId, 0 AS NoRdExist, 0 AS NoRdImp, 
Sum(CASE WHEN(R.SurfaceType='BC') THEN ((R.ToChain-R.FromChain)/1000) END) 
AS BcLenExist, 0 AS BcLenImp
    FROM (RoadInventory AS RI 
        INNER JOIN Thana AS A ON RI.ThanaID = A.Id) 
        INNER JOIN Segment AS R ON (RI.Id = R.RoadID) AND (RI.ThanaID = R.ThanaID) GROUP BY R.ThanaID, RI.RoadTypeId 

UNION SELECT R.ThanaID, RI.RoadTypeId, 0 AS NoRdExist, 0 AS NoRdImp, 0 AS 
BcLenExist, Sum(CASE WHEN(R.SurfaceType='BC') THEN ((R.ToChain-R.FromChain)/1000) END) 
AS BcLenImp
    FROM (RoadInventory_Temp AS RI 
        INNER JOIN Thana AS A ON RI.ThanaID = A.Id) 
        INNER JOIN Segment_Temp AS R ON (RI.Id = R.RoadID) AND (RI.ThanaID = R.ThanaID) GROUP BY R.ThanaID, RI.RoadTypeId 

结果是这样的

ThanaID |RoadTypeId |NoRdExist |NoRdImp |BcLenExist |BcLenImp |
...............................................................
10101   |2          |0         |0       |0          |92
...............................................................
10101   |2          |0         |0       |92         |0
............................................................... 
10101   |2          |0         |8       |0          |0
...............................................................
10101   |2          |8         |0       |0          |0
............................................................... 
10101   |3          |0         |0       |0          |42
...............................................................
10101   |3          |0         |0       |42         |0
...............................................................
10101   |3          |0         |26      |0          |0
...............................................................
10101   |3          |26        |0       |0          |0
...............................................................

现在我想将包含 0(零)的列合并到包含值的列中。像这样

ThanaID |RoadTypeId |NoRdExist |NoRdImp |BcLenExist |BcLenImp |
...............................................................
10101   |2          |8         |8       |92         |92
............................................................... 
10101   |3          |26        |26      |42         |42
...............................................................

我怎样才能挤压这些行?

【问题讨论】:

  • 我不知道您的架构,但快速查看查询表明不需要联合。您也许可以在具有多个连接的单个查询中实现这一点。如果没有,请将此联合与另一个在所需列上使用 sum 函数的 select 包装起来。
  • 简单地说,将当前查询包装为 CTE,然后通过 ThanaID 聚合,获取所有列的总和。或者,按照@danish 的建议,尝试编写一个查询来处理所有事情。
  • 旁注:为什么UNION 而不是简单的UNION ALL?我不认为有任何重复要删除,是吗?那你为什么一直加入Thana 表?你没有使用它。

标签: sql sql-server union


【解决方案1】:

您希望每个 ThanaID 和 RoadTypeId 有一个结果行以及其他值的总和。因此,根据您的查询,您可以简单地聚合:

select thanaid, roadtypeid, sum(nordexist), sum(nordimp), sum(bclenexist), sum(bclenimp)
from ( your query here )
group by thanaid, roadtypeid
order by thanaid, roadtypeid;

(我可能会以不同的方式编写查询,以免在单独的行中获取值,但是对于上面给出的查询,现在查询是最简单的解决方案。)

【讨论】:

  • 嗨。谢谢你的建议。您能分享一下您将如何编写此查询吗?我不能做 SUM,因为我有其他一些包含 VARCHAR 的列
  • 那么您的描述和示例不完整。它不仅是零,也不是零和它们的总和,就像你的例子一样。对于字符串,您可能只是使用空值代替零(您也应该将其用于数值),因此您可以只使用MAX(valueMIN(value)。无论如何,我已经发布了另一个完全避免联合中间结果的答案。
【解决方案2】:

您针对ThanaIDRoadTypeId 运行不同的查询。然后通过UNION 组合它们。目前尚不清楚您为什么要这样做,因为您似乎对 UNION 结果不感兴趣。看来您想要一个合并的结果。可能是内连接,也可能是所有查询的完全外连接;我不知道。下面我展示了所有 ThanaIDRoadTypeId 组合的结果,从而避免了完全外连接,因为在 SQL Server 中,由于缺少 USING 子句,多个完全外连接相当笨拙。

select
  t.id as thanaid,
  rt.id as roadtypeid,
  q1.nordexist,
  q2.nordimp
from thana t
cross join roadtype rt
left join
(
  select thanaid, roadtypeid, count(*) as nordexist 
  from roadinventory 
  group by thanaid, roadtypeid 
) q1 on q1.thanaid = t.id and q1.roadtypeid = rt.id
left join
(
  select thanaid, roadtypeid, count(*) as nordimp
  from roadinventory_temp 
  group by thanaid, roadtypeid 
) q2 on q2.thanaid = t.id and q2.roadtypeid = rt.id
...

【讨论】:

    【解决方案3】:

    Hi group by ThanaID 和 RoadTypeID 然后对字段 NoRdExist,NoRdImp,BcLenExist 求和 和 BcLenImp。 试试这个

    select  ThanaID ,RoadTypeId ,NoRdExist=sum(isnull(NoRdExist,0)),sum(isnull(NoRdImp,0) ) NoRdImp,sum(isnull(BcLenExist,0)  ) as BcLenExist,BcLenImp=sum(isnull(BcLenImp,0)   )  from (
    SELECT R.ThanaID, R.RoadTypeId, Count(R.Id) AS NoRdExist, 0 AS NoRdImp, 0 AS 
    BcLenExist, 0 AS BcLenImp FROM RoadInventory AS R 
            INNER JOIN Thana AS A ON R.ThanaID = A.Id GROUP BY R.ThanaID,R.RoadTypeId 
    
    UNION SELECT R.ThanaID, R.RoadTypeId, 0 AS NoRdExist, Count(R.Id) AS 
    NoRdImp,0 AS BcLenExist, 0 AS BcLenImp FROM RoadInventory_Temp AS R
            INNER JOIN Thana AS A ON R.ThanaID = A.Id GROUP BY R.ThanaID, R.RoadTypeId 
    
    UNION SELECT R.ThanaID, RI.RoadTypeId, 0 AS NoRdExist, 0 AS NoRdImp, 
    Sum(CASE WHEN(R.SurfaceType='BC') THEN ((R.ToChain-R.FromChain)/1000) END) 
    AS BcLenExist, 0 AS BcLenImp
        FROM (RoadInventory AS RI 
            INNER JOIN Thana AS A ON RI.ThanaID = A.Id) 
            INNER JOIN Segment AS R ON (RI.Id = R.RoadID) AND (RI.ThanaID = R.ThanaID) GROUP BY R.ThanaID, RI.RoadTypeId 
    
    UNION SELECT R.ThanaID, RI.RoadTypeId, 0 AS NoRdExist, 0 AS NoRdImp, 0 AS 
    BcLenExist, Sum(CASE WHEN(R.SurfaceType='BC') THEN ((R.ToChain-R.FromChain)/1000) END) 
    AS BcLenImp
        FROM (RoadInventory_Temp AS RI 
            INNER JOIN Thana AS A ON RI.ThanaID = A.Id) 
            INNER JOIN Segment_Temp AS R ON (RI.Id = R.RoadID) AND (RI.ThanaID = R.ThanaID) GROUP BY R.ThanaID, RI.RoadTypeId) as t
            group by ThanaID ,RoadTypeId 
    

    【讨论】:

      猜你喜欢
      • 2011-09-30
      • 1970-01-01
      • 2011-12-21
      • 1970-01-01
      • 1970-01-01
      • 2018-04-22
      • 2017-09-24
      • 2016-07-12
      • 1970-01-01
      相关资源
      最近更新 更多