【问题标题】:Sorting query output by Month name按月份名称对查询输出进行排序
【发布时间】:2020-06-02 09:57:14
【问题描述】:

我正在尝试使用 SQL 查询从 Excel 中提取值,但我一直在努力按各自的顺序对月份进行排序。现在表格正在按 A-Z 排序,我尝试使用 DATEPART,但不是很成功,因为我收到了 Int16 错误。

Select F1,
SUM(F2),
ROUND(SUM(REPLACE(F3, ',', '.')), 2),
ROUND(SUM(REPLACE(F4, ',', '.')), 2)
FROM [Sheet1$]
WHERE F1 IN ('January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December')
GROUP BY F1;

这是有效的查询,但结果是:

我也愿意接受任何可以提高我的查询速度的建议,因为文档很大,大约 50k 行,谢谢。

对于任何想知道最终查询是否有效的人:

Select F1,
SUM(F2),
ROUND(SUM(REPLACE(F3, ',', '.')), 2),
ROUND(SUM(REPLACE(F4, ',', '.')), 2)
FROM [Sheet1$]
WHERE F1 IN ('January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December')
GROUP BY F1
ORDER BY SWITCH(
F1='January', 1,
F1='February', 2,
F1='March', 3,
F1='April', 4,
F1='May', 5,
F1='June', 6,
F1='July', 7,
F1='August', 8,
F1='September', 9,
F1='October', 10,
F1='November', 11,
F1='December', 12
);

【问题讨论】:

  • 如果您需要性能建议,请发布执行计划。
  • 代替 Switch(),考虑:ORDER BY Month([F1] & " 1, 2000")
  • ORDER BY DatePart("m", F1 & " 1 2000")

标签: sql-server tsql date oledb blueprism


【解决方案1】:

要么使用CASE 表达式:

Select
  f1,
  SUM(f2),
  ROUND(SUM(REPLACE(f3, ',', '.')), 2),
  ROUND(SUM(REPLACE(f4, ',', '.')), 2)
FROM [Sheet1$]
WHERE F1 IN ('January', 'February', 'March', 'April', 'May', 'June',
             'July', 'August', 'September', 'October', 'November', 'December')
GROUP BY F1
ORDER BY
  CASE F1
    WHEN 'January' THEN 1
    WHEN 'February' THEN 2
    WHEN 'March' THEN 3
    WHEN 'April' THEN 4
    WHEN 'May' THEN 5
    WHEN 'June' THEN 6
    WHEN 'July' THEN 7
    WHEN 'August' THEN 8
    WHEN 'September' THEN 9
    WHEN 'October' THEN 10
    WHEN 'November' THEN 111
    WHEN 'December' THEN 12
  END;

或者动态创建月份表:

Select
  s.f1,
  SUM(s.f2),
  ROUND(SUM(REPLACE(s.f3, ',', '.')), 2),
  ROUND(SUM(REPLACE(s.f4, ',', '.')), 2)
FROM [Sheet1$] s
JOIN VALUES
(
  ('January', 1),
  ('February', 2),
  ('March', 3),
  ('April', 4),
  ('May', 5),
  ('June', 6),
  ('July', 7),
  ('August', 8),
  ('September', 9),
  ('October', 10),
  ('November', 11),
  ('December', 12)
) months(month_name, month_number) ON s.f1 = months.month_name
GROUP BY s.f1
ORDER BY months.month_number;

或者创建一个真实的月份表。

【讨论】:

  • 在尝试使用第一个建议后,我开始收到错误“无法识别的关键字时间”,所以我做了一些挖掘并发现我需要使用 SWITCH。如果是这种情况,我想我使用的是 MS Access SQL 而不是 SQL Server,但无论如何谢谢。
  • 啊,好吧。 MS Access 与标准 SQL 非常不同。因此,Internet 上的许多 SQL 源都不适用于它,我的查询也不适用。 SQL Server、MySQL、Oracle、PostgreSQL 和许多其他 DBMS 更符合标准。很高兴您找到了解决方案。
【解决方案2】:

你可以这样做:

order by datepart(mm, f1 + ' 1 2000')

【讨论】:

  • 它是mmMonth。不是'mm'。因为它会抛出 "Invalid parameter 1 specified for datepart."
  • 根据 GMB 的建议,我收到一个(无效的过程调用)错误,使用 Sami 提供的建议,我收到一个(没有为一个或多个必需参数提供值)我正在使用 OLE DB 驱动程序如果有帮助,请运行此查询。
  • @GMB 正如我之前提到的,我收到一条错误消息,提示我缺少一个或多个必需参数。 GROUP BY F1order by datepart(mm, f1 + ' 1 2000');
  • 此方法依赖于 SQL Server 识别的这种日期格式(例如“2000 年 2 月 1 日”)。我不认为这是有保证的。
猜你喜欢
  • 2019-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-19
  • 2018-06-19
  • 1970-01-01
  • 1970-01-01
  • 2020-06-22
相关资源
最近更新 更多