【问题标题】:Duplicate Rows - SQL Server Groupby and Union重复行 - SQL Server Group By 和 Union
【发布时间】:2019-03-12 19:55:52
【问题描述】:

我有一些类似以下的数据:

--------------------------------------------------
Location  Weight  MarkedOldest  plantId  Date
--------------------------------------------------
101010    520     0             2        3/10/2019
105000    500     1             2        3/1/2019
105000    500     0             2        2/20/2019

并且要求能够覆盖此表中最旧的行。我在这里介绍了 MarkedOldest 列,以保留创建该行的实际日期。乍一看,您会看到表中的最后一行是最旧的,但是说用户希望将第二行设置为最旧的。没问题。

当我返回这些行的列表并要求显示每个位置的总重量时,我的问题出现了,最旧的位置首先显示。 这样的查询的理想输出将返回:

105000  1000lbs  (3/1 and 2/20)
101010  520lbs   3/10

我已经编写了以下已接近的查询:

select z.Location, Sum(z.Weight), as Weight, z.Date
FROM 
  (select Location, Weight, MarkedOldest
   from dbo.SomeTable WHERE MarkedOldest = 1 PlantId= 2 
   UNION
   select Location, Weight, MarkedOldest
   from dbo.SomeTable WHERE PlantId = 2) as z
Group by z.Location, z.MarkedOldest
Order By z.MarkedOldest desc

此查询产生以下输出:

105000  500lbs  3/1/2019
105000  500lbs  2/20/2019
101010  520lbs  3/10/2019

这里的想法是首先选择任何手动输入的最旧的行,然后以最旧的第一顺序将它们与剩余的行合并。上面的输出几乎是正确的,但我想合并/删除前两行的重复位置。但是我认为我不能这样做,因为我按列“MarkedOldest”和“Date”分组

还有其他方法可以解决此查询以获得预期的输出吗?在尝试删除一些 groupby 或 orderby 列等操作时,我遇到了很多 groupBy/aggregate 错误。

【问题讨论】:

标签: sql sql-server group-by sql-order-by union


【解决方案1】:

您可以做到这一点的一种方法是让 UNION 的上半部分包含“标记为最旧”的行以及它之前的所有行。

WHERE Date<=(SELECT Date FROM MyTable WHERE MarkedOldest=1)

然后您可以对 UNION 的那一半进行 GROUP 和聚合,并使下半部分仅包含“标记为最旧”行之后的行。

WHERE Date>(SELECT Date FROM MyTable WHERE MarkedOldest=1)

上面的代码 sn-ps 假定“标记为最旧”的行不能与不是“标记为最旧”的另一行具有相同的确切日期。如果这是可能的,那么您必须决定要对另一行做什么并相应地编码。

【讨论】:

  • 这不适合我。我可能做错了什么。因为我必须在父查询中选择 MarkedOldest 以首先显示手动最旧的行(按顺序 desc),所以它也必须按它分组,这将两个 100500 位置分成单独的行。
【解决方案2】:

我专注于您的理想输出,如果您将当前输出放入 CTE 并进行一些数据转换,您可以尝试以下查询:

WITH data as(
SELECT 105000 id ,CAST(LEFT('500lbs',LEN('500lbs')-3) AS numeric) AS lbs,  '3/1/2019' AS date union all
SELECT 105000 id ,LEFT('500lbs',LEN('500lbs')-3) AS lbs,  '2/20/2019' AS date union all
SELECT 101010 id ,LEFT('520lbs',LEN('520lbs')-3) AS lbs,  '3/1/2019' AS date
)

SELECT 
    ID
    ,CAST(SUM(lbs) as VARCHAR) +'lbs' lbs
    ,STUFF((SELECT DISTINCT ' and ' + d2.date
                     FROM data d2
                     WHERE d1.ID = d2.ID
                 FOR XML PATH('')) , 1, 5, '') AS  date
FROM data d1
GROUP BY ID

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-11
    • 1970-01-01
    • 2015-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多