【问题标题】:Using a Result Set From a Sub SELECT When Duplicate Rows are Encountered遇到重复行时使用来自子 SELECT 的结果集
【发布时间】:2012-03-12 00:26:05
【问题描述】:

首先,我正在努力解决的表:

DispatchLocations
=================
DispatchID        int
StopNumber        int
Arrived           bool
Departed          bool

这个想法是,在货运路线上,调度中有许多站点。这是每个调度上每个位置的列表(本质上,它是一个路由表)。在这个视图中,每一行输出应该只有一个调度,它指向调度所在的“当前停止”。

SELECT TOP 4
  DispatchID,
  Min(StopNumber) AS NextStop,
  Arrived,
  Departed
FROM DispatchLocations
GROUP BY 
  DispatchID,
  Arrived, Departed
HAVING (Arrived = 0 OR Departed = 0)
ORDER BY DispatchID ASC, NextStop ASC

我现在的视图输出:

Dispatch_ID    NextStop    Arrived    Departed
===========    ========    =======    ========
3              2           False      False
1356           2           False      False
6410           1           True       False
6410           2           False      False

最后一行被转储,因为 GROUP BY 必须包含到达和离开状态,破坏了输出的唯一性。

可以使用非常相似的查询(仅)提取所需的行:

SELECT
  DispatchID,
  Min(StopNumber) AS NextStop,
  Arrived,
  Departed
FROM DispatchLocations
GROUP BY 
  DispatchID,
  Arrived, Departed
HAVING
  (Arrived = 1 AND Departed = 0) AND Min(StopNumber) = 1
ORDER BY DispatchID ASC

Dispatch_ID    NextStop    Arrived    Departed
===========    ========    =======    ========
6410           1           True       False
50589          1           True       False
50687          1           True       False

我通过从我的视图WHERE COUNT(DispatchID) > 1 中选择所有 DispatchID 来验证这些结果。

当我在视图中遇到那些匹配的 ID 时,如何使用第二个查询的结果?我无法让EXISTEXCEPT 子句与查询文本中的HAVING 一起使用。所以现在我将结果从数据库手中拿走,让应用程序逻辑对所有重复的结果进行排序,并只保留每个调度 ID 遇到的第一个结果。但我宁愿让数据库为我做这件事。

更新

我使用的是 SSMS 2008,它默认使用 TOP 100 PERCENT 构建视图。这是原版的pastebin

【问题讨论】:

  • 这是什么关系型数据库?我猜不是 SQL Server,因为您在 VIEW 中有 ORDER BY
  • @JNK - ORDER BY 可以与 TOP 在视图中或需要任何有效表表达式的地方一起使用
  • @JCooper 我意识到这一点,但请注意在发布的视图定义中没有 TOP

标签: sql sql-server-2008 group-by duplicates having


【解决方案1】:

我想你想要这样的东西:

SELECT  dl.DispatchID,
        dl.StopNumber AS NextStop,
        dl.Arrived,
        dl.Departed
FROM    DispatchLocations dl
        INNER JOIN
        (   SELECT  DispatchID, MIN(StopNumber) [StopNumber]
            FROM    DispatchLocations
            GROUP BY DispatchID
        ) MinDL
            ON MinDL.DispatchID = dl.DispatchID
            AND MinDL.StopNumber = dl.StopNumber

这将返回每个调度 ID 的最低停靠点的详细信息。然后,您可以通过简单地使用WHERE 进一步过滤它。例如

WHERE  Arrived = 1
AND    Departed = 0

我认为将上述内容添加到顶部的 select 语句中会返回结果:

Dispatch_ID    NextStop    Arrived    Departed
===========    ========    =======    ========
6410           1           True       False
50589          1           True       False
50687          1           True       False

虽然我可能完全误解了这个问题。

【讨论】:

  • 我想我已经按照这些思路尝试了一些东西,但我会在早上工作时重建我的派生表。到时候我会发布更新。
猜你喜欢
  • 1970-01-01
  • 2018-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-30
  • 2019-11-06
  • 2023-03-20
  • 1970-01-01
相关资源
最近更新 更多