遇到重复行时使用子 SELECT 中的结果集

发布于 2025-01-07 08:35:11 字数 1836 浏览 1 评论 0原文

首先,我正在努力处理的表格:

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

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

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

更新

我正在使用 SSMS 2008,它构建默认包含 TOP 100 PERCENT 的视图。这是原始的 pastebin

First of all, the table I'm struggling with:

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

The idea is that on a trucking route, there are many stops in a dispatch. This is a list of each location on each dispatch (essentially, it's a route table). In this view, there should only be one dispatch for each row of output, which points to the "current stop" that the dispatch is at.

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

My view's output as of now:

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

The last row is being dumped in because the GROUP BY must include the arrival and departure status, breaking the uniqueness of the output.

The desired rows (only) can be extracted using a very similar query:

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

I verified these results by selecting all DispatchIDs from my view WHERE COUNT(DispatchID) > 1.

How can I use the results from the second query whenever I encounter those matching IDs in the view? I can't get an EXIST or an EXCEPT clause to work with HAVING present in the query text. So for now I'm taking the results set off the database's hands, and having the application logic sort through any duplicate results, and keeping only the first one encountered for each dispatch ID. But I'd rather have the database do this for me.

UPDATE

I'm using SSMS 2008, which builds views with a TOP 100 PERCENT included by default. Here's the pastebin of the original.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

九八野马 2025-01-14 08:35:11

我想你想要这样的东西:

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

尽管我可能完全误解了这个问题。

I think you want something like this:

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

This will return the details for the lowest stopnumber for each dispatch ID. You can then filter this further by simply using WHERE. E.g.

WHERE  Arrived = 1
AND    Departed = 0

I think adding the above to the select statement at the top will bring back the results:

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

Although I may have completely misunderstood the question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文