SQL Server DISTINCT 分页与 ROW_NUMBER() 不不同

发布于 2024-12-16 13:17:51 字数 750 浏览 0 评论 0原文

好吧,基本上我的 DISTINCT 通过使用 ROW_NUMBER() 变得毫无用处,我需要避免这种情况,因为它会导致重复的结果(当然除了唯一的数字!

)我正在寻找的是一个工作原理相同但没有重复行的查询,因为 num 是唯一的:

WITH t AS
(
   SELECT DISTINCT *, ROW_NUMBER() OVER (ORDER BY Date) AS num 
   FROM Original_Import 
   LEFT JOIN eqcas.dbo.BASE_PROXY_VIEW_WITHTARGET ON ADName = Targetuser
   WHERE (BaseProxy = 'agmc' OR ADName = 'agmc')
      AND (Commited IS NULL OR Commited = 0)
)
SELECT DISTINCT ID, num, ADName, Description_User, Description_Amex, Amount, Date
FROM t 
WHERE (t.BaseProxy = 'agmc' OR t.ADName = 'agmc') 
   AND num BETWEEN 0 AND 20
   AND (Commited IS NULL OR Commited = 0)
ORDER BY Date

修复起来可能相当简单,但由于我不是 SQL Server 人员,所以我不习惯这些内部查询等等..

更新:是的,num 用于分页。

Ok, so basically my DISTINCT is rendered useless by using ROW_NUMBER(), I need to avoid this as it's causing duplicate results (apart from a unique num of course!)

So what I'm looking for is a query that'll work the same but not have duplicate rows because num is unique:

WITH t AS
(
   SELECT DISTINCT *, ROW_NUMBER() OVER (ORDER BY Date) AS num 
   FROM Original_Import 
   LEFT JOIN eqcas.dbo.BASE_PROXY_VIEW_WITHTARGET ON ADName = Targetuser
   WHERE (BaseProxy = 'agmc' OR ADName = 'agmc')
      AND (Commited IS NULL OR Commited = 0)
)
SELECT DISTINCT ID, num, ADName, Description_User, Description_Amex, Amount, Date
FROM t 
WHERE (t.BaseProxy = 'agmc' OR t.ADName = 'agmc') 
   AND num BETWEEN 0 AND 20
   AND (Commited IS NULL OR Commited = 0)
ORDER BY Date

It's probably fairly trivial to fix, but seeing as I'm not a SQL Server guy I'm not used to these inner queries etc..

Update: yes, num is used for paging.

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

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

发布评论

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

评论(2

悲凉≈ 2024-12-23 13:17:51

好像我最近发表的关于 ROW_NUMBER()SELECT 什么DENSE_RANK()SELECT DISTINCT。您的 CTE 必须替换为:

WITH t AS
(
   SELECT DISTINCT *, DENSE_RANK() OVER (ORDER BY Date, ...) AS num 
   FROM Original_Import 
   LEFT JOIN eqcas.dbo.BASE_PROXY_VIEW_WITHTARGET ON ADName = Targetuser
   WHERE (BaseProxy = 'agmc' OR ADName = 'agmc')
      AND (Commited IS NULL OR Commited = 0)
)
SELECT ...

在上面的查询中,DENSE_RANK()ORDER BY 子句需要列出 Original_Import< 中的所有列/code> 和来自 BASE_PROXY_VIEW_WITH_TARGET,以重现与 DISTINCT 关键字相同的顺序。这将为每个重复记录集分配一个排名,这样 DISTINCT 将再次起作用。

参考博客文章,我还添加了一个 SQLFiddle 在一个更简单的示例中说明了这一点。

SELECT DISTINCT
  v, 
  DENSE_RANK() OVER (w) row_number
FROM t
WINDOW w AS (ORDER BY v)
ORDER BY v, row_number

解释为什么DISTINCT在计算窗口函数后删除重复行可以在这篇文章中找到

Seems like I'm two years late with my recent blog post about ROW_NUMBER() being to SELECT what DENSE_RANK() is to SELECT DISTINCT. Your CTE would have to be replaced by this:

WITH t AS
(
   SELECT DISTINCT *, DENSE_RANK() OVER (ORDER BY Date, ...) AS num 
   FROM Original_Import 
   LEFT JOIN eqcas.dbo.BASE_PROXY_VIEW_WITHTARGET ON ADName = Targetuser
   WHERE (BaseProxy = 'agmc' OR ADName = 'agmc')
      AND (Commited IS NULL OR Commited = 0)
)
SELECT ...

In the above query, the DENSE_RANK()'s ORDER BY clause will need to list all columns from Original_Import and from BASE_PROXY_VIEW_WITH_TARGET, to reproduce the same ordering as the DISTINCT keyword. That will assign exactly one rank per duplicate record set, such that DISTINCT will work again.

In the referenced blog post, I have also included a link to a SQLFiddle illustrating this in a more trivial example.

SELECT DISTINCT
  v, 
  DENSE_RANK() OVER (w) row_number
FROM t
WINDOW w AS (ORDER BY v)
ORDER BY v, row_number

An explanation why DISTINCT removes duplicate rows after window functions having been calculated can be found in this post here.

淡淡的优雅 2024-12-23 13:17:51

对此信心有限,因为我无法测试甚至编译,但这是我的想法的一般要点......

WITH t AS
(
   SELECT [insert your fields here], ROW_NUMBER() OVER (ORDER BY Date) AS num 
   FROM (
     SELECT DISTINCT *[insert your fields here]
     FROM Original_Import 
     LEFT JOIN eqcas.dbo.BASE_PROXY_VIEW_WITHTARGET ON ADName = Targetuser
     WHERE (BaseProxy = 'agmc' OR ADName = 'agmc')
      AND (Commited IS NULL OR Commited = 0)) as X
)
SELECT DISTINCT ID, num, ADName, Description_User, Description_Amex, Amount, Date
FROM t 
WHERE (t.BaseProxy = 'agmc' OR t.ADName = 'agmc') 
   AND num BETWEEN 0 AND 20
   AND (Commited IS NULL OR Commited = 0)
ORDER BY Date

limited confidence on this as I can't test or even compile but this is the general gist of what I was thinking...

WITH t AS
(
   SELECT [insert your fields here], ROW_NUMBER() OVER (ORDER BY Date) AS num 
   FROM (
     SELECT DISTINCT *[insert your fields here]
     FROM Original_Import 
     LEFT JOIN eqcas.dbo.BASE_PROXY_VIEW_WITHTARGET ON ADName = Targetuser
     WHERE (BaseProxy = 'agmc' OR ADName = 'agmc')
      AND (Commited IS NULL OR Commited = 0)) as X
)
SELECT DISTINCT ID, num, ADName, Description_User, Description_Amex, Amount, Date
FROM t 
WHERE (t.BaseProxy = 'agmc' OR t.ADName = 'agmc') 
   AND num BETWEEN 0 AND 20
   AND (Commited IS NULL OR Commited = 0)
ORDER BY Date
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文