为啥在sql sever中使用first和last函数查询,提示‘first’'last' 不是可以识别的 内置函数名称。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥在sql sever中使用first和last函数查询,提示‘first’'last' 不是可以识别的 内置函数名称。相关的知识,希望对你有一定的参考价值。
select last(year) as firstyear from persons;
sql sever2008 不支持first和last ,2012支持,你可以用BETWEEN ... AND来查询结果是一样的! 参考技术A 使用MIN 与 MAX 函数, 来替换掉 first 和 last
如果是要获取 表里面 第一行数据的 year
select top 1 year as firstyear from persons;
最后一行, 有点复杂...
create table firstl(
orderdate date,
orderprice int);
insert into firstl values('2008/12/29','1000');
insert into firstl values('2008/11/23','1600');
insert into firstl values('2008/10/05','700');
insert into firstl values('2008/09/28','300');
GO
1>
2> SELECT top 1 orderdate FROM firstl
3> GO
orderdate
----------------
2008-12-29
(1 行受影响)
1>
2> SELECT
3> top 1 orderdate
4> FROM
5> (
6> SELECT
7> ROW_NUMBER() OVER( ORDER BY (SELECT 1)) NO,
8> orderdate
9> FROM
10> firstl
11> ) subQuery
12> ORDER BY
13> NO DESC
14> GO
orderdate
----------------
2008-09-28
(1 行受影响)
SQL Server 2008 Express 版本下测试通过。 参考技术B 用的位置不对,sql解析不正确报的错。 参考技术C 你是oracle还是sql server啊 参考技术D select cast(year as int)-1 as firstyear from persons
前提是YEAR这个字段只是保存年比如:“2013”
那么“2013-1”就是上2012了追问
create table firstl
(orderdate date,
orderprice int);
insert into firstl values('2008/12/29','1000');
insert into firstl values('2008/11/23','1600');
insert into firstl values('2008/10/05','700');
insert into firstl values('2008/09/28','300');
select first(orderprice) as firstprice from firstl;
重新写了个直接是int型的,可是依然报错
select cast(convert(varchar(4),orderprice,121) as int)-1 as firstprice from firstl;
Spark SQL 可以在 GROUP BY 聚合中使用 FIRST_VALUE 和 LAST_VALUE(但这不是标准的)
【中文标题】Spark SQL 可以在 GROUP BY 聚合中使用 FIRST_VALUE 和 LAST_VALUE(但这不是标准的)【英文标题】:Spark SQL can use FIRST_VALUE and LAST_VALUE in a GROUP BY aggregation (but it's not standard) 【发布时间】:2018-07-11 09:00:53 【问题描述】:(在 Spark 2.2 和 2.3 上测试)
我正在使用 Spark 将股票交易报价汇总到每日 OHLC(开盘-高-低-收)记录中。
输入的数据是这样的
val data = Seq(("2018-07-11 09:01:00", 34.0), ("2018-07-11 09:04:00", 32.0), ("2018-07-11 09:02:00", 35.0), ("2018-07-11 09:03:00", 30.0), ("2018-07-11 09:00:00", 33.0), ("2018-07-12 09:01:00", 56.0), ("2018-07-12 09:04:00", 54.0), ("2018-07-12 09:02:00", 51.0), ("2018-07-12 09:03:00", 50.0), ("2018-07-12 09:00:00", 51.0)).toDF("time", "price")
data.createOrReplaceTempView("ticks")
data.show
scala>
显示为
+-------------------+-----+
| time|price|
+-------------------+-----+
|2018-07-11 09:01:00| 34.0|
|2018-07-11 09:04:00| 32.0|
|2018-07-11 09:02:00| 35.0|
|2018-07-11 09:03:00| 30.0|
|2018-07-11 09:00:00| 33.0|
|2018-07-12 09:01:00| 56.0|
|2018-07-12 09:04:00| 54.0|
|2018-07-12 09:02:00| 51.0|
|2018-07-12 09:03:00| 50.0|
|2018-07-12 09:00:00| 51.0|
+-------------------+-----+
想要的输出是
+----------+----+----+----+-----+
| date|open|high| low|close|
+----------+----+----+----+-----+
|2018-07-11|33.0|35.0|30.0| 32.0|
|2018-07-12|51.0|56.0|50.0| 54.0|
+----------+----+----+----+-----+
已经有this和this等多种SQL解决方案。
SELECT
TO_DATE(time) AS date,
FIRST_VALUE(price) OVER (PARTITION BY TO_DATE(time) ORDER BY time) AS open,
MAX(price) OVER (PARTITION BY TO_DATE(time) ORDER BY time) AS high,
MIN(price) OVER (PARTITION BY TO_DATE(time) ORDER BY time) AS low,
LAST_VALUE(price) OVER (PARTITION BY TO_DATE(time) ORDER BY time) AS close
FROM ticks
由于SQL的限制,这些方案比较繁琐。
今天,我发现 Spark SQL 可以在 GROUP BY
上下文中使用 FIRST_VALUE
和 LAST_VALUE
which is not allowed in standard SQL。
Spark SQL 的这种无限性衍生出一个整洁的解决方案,如下所示:
SELECT
TO_DATE(time) AS date,
FIRST_VALUE(price) AS open,
MAX(price) AS high,
MIN(price) AS low,
LAST_VALUE(price) AS close
FROM ticks
GROUP BY TO_DATE(time)
你可以试试
spark.sql("SELECT TO_DATE(time) AS date, FIRST(price) AS open, MAX(price) AS high, MIN(price) AS low, LAST(price) AS close FROM ticks GROUP BY TO_DATE(time)").show
scala>
显示为
+----------+----+----+----+-----+
| date|open|high| low|close|
+----------+----+----+----+-----+
|2018-07-11|34.0|35.0|30.0| 33.0|
|2018-07-12|56.0|56.0|50.0| 51.0|
+----------+----+----+----+-----+
但是,上面的结果是不正确的。 (请与上述预期结果进行比较。)
FIRST_VALUE
和 LAST_VALUE
需要确定性排序才能获得确定性结果。
我可以通过在分组前添加orderBy
来纠正它。
import org.apache.spark.sql.functions._
data.orderBy("time").groupBy(expr("TO_DATE(time)").as("date")).agg(first("price").as("open"), max("price").as("high"), min("price").as("low"), last("price").as("close")).show
scala>
显示为
+----------+----+----+----+-----+
| date|open|high| low|close|
+----------+----+----+----+-----+
|2018-07-11|33.0|35.0|30.0| 32.0|
|2018-07-12|51.0|56.0|50.0| 54.0|
+----------+----+----+----+-----+
根据需要正确!!!
我的问题是,上面的代码“orderBy then groupBy”是否有效?这个订购有保证吗?我们可以在严肃的作品中使用这种非标准功能吗?
这个问题的重点是,在标准 SQL 中,我们只能先执行 GROUP BY
然后 ORDER BY
对聚合进行排序,而不是 ORDER BY
然后 GROUP BY
。
GROUP BY
将忽略 ORDER BY
的顺序。
我也想知道 Spark SQL 是否可以在所需的顺序下执行这样的GROUP BY
,标准 SQL 是否也可以为此发明这样的语法?
附言
我可以想到一些依赖于确定性排序的聚合函数。
WITH ORDER BY time SELECT COLLECT_LIST(price) GROUP BY stockID
WITH ORDER BY time SELECT SUM(SQUARE(price - LAG(price, 1, 0))) GROUP BY stockID
如果没有WITH ORDER BY time
,我们如何在标准 SQL 中对 COLLECTed_LIST 进行排序?
这些例子表明“GROUP BY
under desired ordering”仍然有用。
【问题讨论】:
我想知道如果我们可以这样使用它,提供first_value, last_value
有什么意义,如果不是这样,预期的用例是什么? :(
如果某个查询结果是有序的,并且它的分组是保序的,那么我们可以一次获得first_value,last_value,min,max,sum,count ...。不需要多个 partition-by 语句。我相信 spark 的 orderby+groupby 是保序的,因为我在上面的例子中得到了正确的结果。
至于用例,我在 P.S. 中展示了 2:COLLECT_LIST
和 price - LAG(price)
。我的问题的一部分。真正的预期用例是真正为股票价格计算 OHLC。
【参考方案1】:
groupBy/agg 中的排序不保证,可以使用窗口函数,按键分区和时间排序
【讨论】:
我没有选择你的答案,因为我无法判断你所说的“不保证”是否属实。也许有保证但没有记录?如果您提供更多证据,例如文档或源代码研究,我会选择您的答案。谢谢。 您提供的关于窗口功能的内容是我问题中超链接中已知的解决方案之一。我的问题是基于此。为了澄清,我刚刚编辑了我的问题以添加窗口 SQL 语句。以上是关于为啥在sql sever中使用first和last函数查询,提示‘first’'last' 不是可以识别的 内置函数名称。的主要内容,如果未能解决你的问题,请参考以下文章
MySQL中为啥不能在select语句中使用into将查询结果存入新表,但是SQL sever可以
Impala 中 FIRST() 和 LAST() 的等价物
为啥 std::find_if(first, last, p) 不采用引用谓词?
为啥 std::distance() for std:list<int>::iterator 在 last 在 first 之前不返回负数?