【问题标题】:Restrict rows in SQL Server table限制 SQL Server 表中的行
【发布时间】:2017-08-29 22:27:47
【问题描述】:

我有一张表IdentifySlot,其中包含如下数据:

Cname   TotalEmpty
------------------
CName1      4
CName2      3
CName3      1
CName4      7
CName5     30
CName6     36

我还有一个ActualSlot 表:

CName   AppDate       RankNumber
--------------------------------
CName1  05/01/2018        1
CName1  05/01/2018        2
CName1  16/02/2018        3
CName2  05/01/2018        1
CName2  19/01/2018        2
CName2  17/02/2018        3
CName2  18/02/2018        4
CName2  19/02/2018        5
CName2  20/02/2018        6
CName3  15/01/2018        1
CName3  16/02/2018        2
CName3  21/02/2018        3
CName4  12/01/2018        1
CName4  02/02/2018        2
CName5  14/01/2018        1
CName5  02/02/2018        2
CName5  22/02/2018        3
CName6  26/01/2018        1
CName6  09/02/2018        2
CName6  09/02/2018        3
Cname+n date+n            n

我想限制这样的行:我想使用IdentifySlot 表中的TotalEmpty 列,并将ActualSlot 表中的行限制为

  • CName1 为 4 行,
  • 3 行 CName2
  • 1 行 CName3
  • CName4 和 7 行
  • CName5 等 30 行...

来自ActualSlot 表。

这是我迄今为止尝试过的:

SELECT TOP (b.TotalEmpty) 
    ApptID, CName, AppDate
FROM
    ActualSlot  a 
LEFT JOIN
    ActualSlot b ON a.CName = b.CName
WHERE
    b.CName = 'CName1'

UNION

SELECT TOP (b.TotalEmpty) 
    ApptID, CName, AppDate
FROM 
    ActualSlot  a 
LEFT JOIN 
    ActualSlot b ON a.CName = b.CName
WHERE 
    b.CName = 'CName2'

UNION

SELECT TOP (b.TotalEmpty) 
    ApptID, CName, AppDate
FROM 
    ActualSlot  a 
LEFT JOIN 
    ActualSlot b ON a.CName = b.CName
WHERE 
    b.CName = 'CName3'

但它不起作用。我想我需要编写一个存储过程来一次循环一个'CNames'而不是联合......感谢任何帮助

【问题讨论】:

  • 如果你愿意,你可以使用交叉应用或类似的东西。例如SELECT b.* FROM IdentifySlot AS a CROSS APPLY (SELECT TOP (a.TotalEmpty) * FROM ActualSlot AS b WHERE b.CName = a.CName) AS b;
  • ranknumber 是实际槽表中的一列吗?
  • 是的 ranknumber 是一列

标签: sql sql-server sql-server-2008 stored-procedures


【解决方案1】:

您可以在这样的子查询中使用 ROW_NUMBER:

SELECT CName, AppDate, RankNumber FROM (
    ApptID,
    CName,
    AppDate, 
    ROW_NUMBER() OVER(PARTITION BY Cname ORDER BY AppDate) RankNumber
    From ActualSlot
) a 
Left Join ActualSlot b on a.CName= b.CName
WHERE  b.CName = 'CName1'
AND RankNumber <= b.TotalEmpty
UNION ALL
..

【讨论】:

    【解决方案2】:

    您是否正在寻找这样的结果?

    SELECT b.totalempty,
           a.cname,
           a.appdate
      FROM actualslot  a 
     INNER JOIN identifyslot b 
        ON a.cname = b.cname
       AND a.ranknumber <= b.totalempty
    

    结果

    totalempty  cname   appdate     ranknumber
    4           CName1  2018-01-05  1
    4           CName1  2018-01-05  2
    4           CName1  2018-02-16  3
    3           CName2  2018-01-05  1
    3           CName2  2018-01-19  2
    3           CName2  2018-02-17  3
    1           CName3  2018-01-15  1
    7           CName4  2018-01-12  1
    7           CName4  2018-02-02  2
    30          CName5  2018-01-14  1
    30          CName5  2018-02-02  2
    30          CName5  2018-02-22  3
    36          CName6  2018-01-26  1
    36          CName6  2018-02-09  2
    36          CName6  2018-02-09  3
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-01
      • 2015-11-05
      • 1970-01-01
      相关资源
      最近更新 更多