【问题标题】:Select top N rows from table Column containing N从包含 N 的表列中选择前 N 行
【发布时间】:2013-02-06 01:46:28
【问题描述】:

TSQL 2008 R2

对于给定的 PO#,我有重复的行项目,每个项目都有自己的唯一 ID。我需要删除重复项。我不知道每个 PO# 有多少重复项。因为有一个#LineItems 我知道我只想要第一个(顶部)x(#lineIems)行项目。

我有一张这样的桌子:

LineitemID PO#     #LineItems
---------- ------- ----------
11111111   12345   3
22222222   12345   3
33333333   12345   3
44444444   12345   3
55555555   12345   3
66666666   12345   3
77777777   54321   2
88888888   54321   2
99999999   54321   2
10101010   54321   2
...  

我需要这样一张桌子:

LineitemID PO#     #LineItems
---------- ------- ----------
11111111   12345   3
22222222   12345   3
33333333   12345   3
77777777   54321   2
88888888   54321   2
...  

所以基本上有办法做这样的事情:

DECLARE @top int = (SELECT TOP 1 FROM tblLineItems t WHERE t.PO# = @PO)

SELECT TOP (@top)
FROM tblLineItems

每个 PO# 都这样做

【问题讨论】:

  • 感谢@LittleBobbyTables。你只是写了我的想法!编辑: Previoius 评论已被删除 - 所以你能解释一下你想要的输出吗?为什么第 4444444、5555555、666666 行不见了?消除线条的当之无愧的规则是什么?第 888888 行的 po# 43125 来自哪里?
  • 哦,我明白你现在要做什么了。 @Nico - LineItems 列确定每个 PO# 返回的行数。 Archangel33,当您说“消除”时,您的意思是“从查询中排除”还是“从表中删除”?
  • @LittleBobbyTables 如果 LineItems 描述每个 PO# 返回多少行 - LineitemID 为 7777777 和 888888 的第二行在所需的 OP 表中在哪里?
  • @LittleBobbyTables 是的,当我说消除时,我的意思是从表中删除。
  • @Nico 抱歉,PO# 43125 是一个错误,我已在问题中解决了这个问题。 #LineItems 列确定结果表中需要多少行

标签: sql tsql select sql-server-2008-r2


【解决方案1】:

facepalm 后删除了第一个答案。

您的示例的唯一问题是您没有在 TOP 查询中 ORDER BY,这可能会以任何顺序提取结果。此查询假定您按 LineItemID(整数类型)ASC 排序。

DECLARE @LineItems TABLE
(
    LineItemID INT
    , PO INT
    , NumLineItems INT
)

INSERT INTO @LineItems (LineItemID, PO, NumLineItems)
SELECT 11111111,   12345,   3
UNION ALL SELECT 22222222,   12345,   3
UNION ALL SELECT 33333333,   12345,   3
UNION ALL SELECT 44444444,   12345,   3
UNION ALL SELECT 55555555,   12345,   3
UNION ALL SELECT 66666666,   12345,   3
UNION ALL SELECT 77777777,   54321,   2
UNION ALL SELECT 88888888,   54321,   2
UNION ALL SELECT 99999999,   54321,   2
UNION ALL SELECT 10101010,   54321,   2

DELETE b
FROM
(
    SELECT *
        , RANK() OVER (PARTITION BY PO, NumLineItems ORDER BY LineItemID ASC) AS r
    FROM @LineItems
) a
JOIN @LineItems b
    ON a.LineItemID = b.LineItemID
WHERE r > a.NumLineItems

SELECT *
FROM @LineItems
ORDER BY PO, LineItemID

【讨论】:

    【解决方案2】:
    delete t from (select *, rank = row_number() over (partition by PO# order by lineitemid) 
                   from table ) t 
    where rank > #lineitems
    

    【讨论】:

    • 如果 OP 想要检索数据,您还必须提供 SELECT 查询。
    猜你喜欢
    • 2012-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多