【问题标题】:Query to get specific row MS SQL Server:查询以获取特定行 MS SQL Server:
【发布时间】:2013-06-10 08:36:26
【问题描述】:

我有一个奇怪的请求。在下表中,我有 vendorno.、act no.、part no. 和 movein_date。我想选择零件编号的行。对于每个 act_no,它在 U13 进入之前最后出现(对于 U13 partno 的 movein_date 最接近过去的 movein_date)。

示例:

1.  Vendor_No Act_num Part_Num Movein_Date
2.  708     3321386 T01     2/19/2012
3.  708     3321386 U13     2/15/2012
4.  708     3321386 U01     2/1/2012
5.  708     3321386 T14     1/31/2012
6.  708     3321386 Y10     1/30/2012
7.  708     3321386 U05     12/31/2011
8.  106     3852820 U13     12/30/2012
9.  106     3852820 T28     12/28/2012
10. 106     3852820 U09     11/12/2012
11. 106     3852820 U01     10/24/2012
12. 106     3852820 T09     4/21/2012
13. 472     3925527 U14     8/3/2012
14. 472     3925527 U13     7/3/2012
15. 472     3925527 T01     1/6/2012
16. 472     3925527 T05     1/6/2012
17. 472     3925527 T14     6/12/2011
18. 472     3925527 U01     5/31/2011
19. 685     4938653 U13     1/28/2013
20. 685     4938653 W20     1/20/2013
21. 685     4938653 U01     1/2/2013
22. 685     4938653 W17     12/25/2012
23. 685     4938653 T05     12/20/2012

我需要的结果:

1.  Vendor_No   Act_num Part_Num    Movein_Date
2.  708 3321386 U01 2/1/2012
3.  106 3852820 T28 12/28/2012
4.  472 3925527 T01 1/6/2012
5.  472 3925527 T05 1/6/2012
6.  685 4938653 W20 1/20/2013

如果我不清楚,请告诉我。

【问题讨论】:

  • 您的 SQL Server 版本是多少?
  • 我正在使用 2008R2 进行查询,但我认为数据库是在 2005 年设置的

标签: sql sql-server sql-server-2005 group-by


【解决方案1】:

一种方法是使用 RANK 函数:

SELECT *
FROM (SELECT *, RANK () OVER(PARTITION BY ACT_NUM ORDER BY Movein_Date DESC)'RowRank'
      FROM Table1
      )a
JOIN (SELECT *, RANK () OVER(PARTITION BY ACT_NUM ORDER BY Movein_Date DESC)'RowRank'
      FROM Table1
      )b
 ON a.RowRank = b.RowRank +1
AND a.ACT_NUM = b.ACT_NUM
 AND b.Part_Num = 'U13'

RANK 基本上只是根据 Movein_Date 对行进行编号,然后您可以通过 JOINING 在 RowRank + 1 上获得一行偏移量。

这是一个演示:SQL Fiddle 注意:忽略“ID”字段,它只是从您的示例中复制的行号。

编辑:错过了每个帐号部分,已修复。

【讨论】:

  • 我还没试过这个查询。但我会在我有空闲时间下班时尝试。感谢您的回复
【解决方案2】:

我手头没有数据库,但在我的脑海中,这样的事情应该可以为您提供所需的基本数据(您需要从 myTable 更改表名):

Select Act_num, max(Movein_date) maxdate
from myTable 
where Movein_date < (Select max(Movein_date) from myTable where part_num = 'U13') 
and part_num != 'U13'
group by Act_num

然后将其连接回自身应该会给你最终的数据集:

Select * 
from myTable tab1 
inner join (
      Select Act_num, max(Movein_date) maxdate
      from myTable 
      where Movein_date < (Select max(Movein_date) from myTable where part_num = 'U13') 
      group by Act_num
) tab2 
on tab1.Act_num = tab2.Act_Num and tab1.Movein_date = tab2.maxdate

【讨论】:

  • 我收到错误:子查询返回超过 1 个值。当子查询跟随 =、!=、、>= 或子查询用作表达式时,这是不允许的。
  • 现在试试,只是改了子查询,更正了列名
  • 现在可以使用了。谢谢您的帮助!!!我很想知道有没有这样的练习题的书或网站。当涉及到聚合、子查询时,我对这类查询非常熟悉。知道的请帮忙。再次感谢您对我的帮助。
  • 我在学习 tSQl 时最喜欢的 tsql 书是 ken hendersons - The-Gurus-Guide-Transact-SQL ,现在可能有点过时了,但它足够小,可以通过几天。我还在 Joe Celkos 的书中看到了很多好东西。
  • 感谢您的回复。我会去找这些书。非常感谢。
猜你喜欢
  • 2020-07-20
  • 1970-01-01
  • 2019-07-29
  • 1970-01-01
  • 2017-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-29
相关资源
最近更新 更多