【问题标题】:Selecting rows with the nearest date using SQL使用 SQL 选择日期最近的行
【发布时间】:2012-08-10 11:55:27
【问题描述】:

我有一条 SQL 语句。

SELECT 
    ID, LOCATION, CODE,MAX(DATE),FLAG 
FROM 
    TABLE1 
WHERE 
     DATE <= CONVERT(DATETIME,'11-11-2012') 
     AND EXISTS (SELECT * FROM #TEMP_CODE WHERE TABLE1.CODE = #TEMP_CODE.CODE) 
     AND ID IN (14, 279)
GROUP BY 
     ID, LOCATION, CODE

我需要日期与 2012 年 11 月 11 日最近的行,但该表会返回所有值。我究竟做错了什么。谢谢

ID     LOCATION              CODE            DATE              FLAG
-------------------------------------------------------------------
14  CAR STREET,UDUPI         234      2012-08-08 00:00:00.000   0
14  CAR STREET,UDUPI         234      2012-08-10 00:00:00.000   1
14  CAR STREET,UDUPI         234      2012-08-14 00:00:00.000   0
279 MADHUGIRI                234      2012-08-08 00:00:00.000   1
279 MADHUGIRI                234      2012-08-11 00:00:00.000   0

我只想显示日期小于或等于给定日期的行。需要的结果是

ID     LOCATION              CODE            DATE              FLAG
-------------------------------------------------------------------
14  CAR STREET,UDUPI         234      2012-08-10 00:00:00.000   1
279 MADHUGIRI                234      2012-08-11 00:00:00.000   0

【问题讨论】:

  • 首先,您为什么使用'11-11-2012' 作为您的日期格式?试试'20121111'。还有为什么第一行是 8 月 10 日而不是 8 月 14 日?
  • @ Aaron Bertrand 我将其作为用户输入。我什至尝试使用 20121111 格式,但没有运气返回所有五列
  • 你表中的所有记录都是
  • @AdRock LIMIT 在 SQL Server 中不存在。
  • 那么您能解释一下为什么 ID = 14 时“2012-08-10”比“2012-08-14”“更近”吗?

标签: sql-server date exists


【解决方案1】:
;WITH x AS 
(
  SELECT ID, Location, Code, Date, Flag, 
    rn = ROW_NUMBER() OVER 
    (PARTITION BY ID, Location, Code ORDER BY [Date] DESC)
  FROM dbo.TABLE1 AS t1
  WHERE [Date] <= '20121111'
  AND ID IN (14, 279) -- sorry, missed this
  AND EXISTS (SELECT 1 FROM #TEMP_CODE WHERE CODE = t1.CODE)
)
SELECT ID, Location, Code, Date, Flag
FROM x WHERE rn = 1;

这会产生:

ID  LOCATION         CODE [Date]     FLAG
--- ---------------- ---- ---------- ----
14  CAR STREET,UDUPI 234  2012-08-14 0
279 MADHUGIRI        234  2012-08-11 0

这与您要求的结果不一致,但我认为这些是错误的,我认为您应该检查它们。

【讨论】:

  • 要求的结果应该是小于 20121111 并且最接近 20121111 的行
  • @Prince 20120814 不是比 20120810 更接近 2012111 吗?或者你能以不同的方式解释为什么你想要 20120810 的行而不是 20120814 的行吗?我只能以多种方式提出这个问题——现在已经是 3 次或 4 次了。请解释得更好。
【解决方案2】:

使用子查询获取每个 ID 的最大日期,然后将其连接到您的表中:

SELECT 
    ID, LOCATION, CODE, DATE, FLAG 
FROM 
    TABLE1 
JOIN (
    SELECT ID AS SubID, MAX(DATE) AS SubDATE 
    FROM TABLE1 
    WHERE DATE < '11/11/2012'
        AND EXISTS (SELECT * FROM #TEMP_CODE WHERE TABLE1.CODE = #TEMP_CODE.CODE) 
        AND ID IN (14, 279)
    GROUP BY ID
    ) AS SUB ON ID = SubID AND DATE = SubDATE

【讨论】:

    【解决方案3】:

    按日期限制 0,2 添加订单

    按照您的顺序,您将按照最接近您的条件的日期排序,并且限制将仅返回前 2 个值!

    SET ROWCOUNT 2  
    SELECT 
        ID, LOCATION, CODE,MAX(DATE),FLAG 
    FROM 
        TABLE1 
    WHERE 
         DATE <= CONVERT(DATETIME,'11-11-2012') 
         AND EXISTS (SELECT * FROM #TEMP_CODE WHERE TABLE1.CODE = #TEMP_CODE.CODE) 
         AND ID IN (14, 279)
    GROUP BY 
         ID, LOCATION, CODE
    ORDER BY DATE
    

    【讨论】:

    • 这正是我的想法
    • LIMIT 在 SQL Server 中不存在(也不存在任何 ANSI/ISO SQL 标准)
    • 我没有看到它是 sql server 所以这种方式只改变了 SET ROWCOUNT 2 的限制。并且硬编码的 ID 是他的 sql 查询看看它。我刚刚添加了订单。
    • 这仍然不起作用。您还需要按 FLAG 分组(在这种情况下,您可能根本不会得到正确的结果),或者您可以对其执行 MIN/MAX,但随后您可能会得到特定行的错误 FLAG。如果我 GROUP BY 标志,我得到两行 ID 14,没有行 ID 279。如果我 MAX() 标志我必须转换为 tinyint,我得到一个标志 1 而不是预期的 0。
    猜你喜欢
    • 2015-06-21
    • 1970-01-01
    • 2021-01-30
    • 2011-05-04
    • 2011-10-24
    • 2014-09-17
    • 2014-09-02
    • 2012-04-15
    • 2013-06-06
    相关资源
    最近更新 更多