- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如何在 T-SQL 中累积值? AFAIK 没有 ARRAY 类型。
我想在同一个查询中重复使用这些值,就像这个 PostgreSQL 示例中使用 array_agg() 所示的那样。 .
SELECT a[1] || a[i] AS foo
, a[2] || a[5] AS bar -- assuming we have >= 5 rows for simplicity
FROM (
SELECT array_agg(text_col ORDER BY text_col) AS a
, count(*)::int4 AS i
FROM tbl
WHERE id BETWEEN 10 AND 100
) sub;
如何使用T-SQL最好地解决这个问题?
我能想到的最好的办法是两个 CTE 和子选择:
;WITH x AS (
SELECT row_number() OVER (ORDER BY name) AS rn
, name AS a
FROM #t
WHERE id BETWEEN 10 AND 100
)
, i AS (
SELECT count(*) AS i
FROM x
)
SELECT (SELECT a FROM x WHERE rn = 1) + (SELECT a FROM x WHERE rn = i) AS foo
, (SELECT a FROM x WHERE rn = 2) + (SELECT a FROM x WHERE rn = 5) AS bar
FROM i;
测试设置:
CREATE TABLE #t(
id INT PRIMARY KEY
, name NVARCHAR(100))
;
INSERT INTO #t VALUES
( 3, 'John')
, ( 5, 'Mary')
, ( 8, 'Michael')
, (13, 'Steve')
, (21, 'Jack')
, (34, 'Pete')
, (57, 'Ami')
, (88, 'Bob')
;
有没有更简单的方法?
最佳答案
编辑 1:我添加了另一个解决方案,展示如何在 SQL Server 上模拟 ARRAY_AGG(最后一个答案)。
编辑2:对于解决方案编号4),我添加了第三种连接方法。
我不确定我是否正确理解了您的问题。
a) 我不会在 SQL Server 中使用数组,而是使用表变量或 XML。
b)要连接字符串(在本例中),我将使用 SELECT @var = @var + Name FROM tbl
语句或 XML xqueries
。
c) 基于CTE和多个子查询的解决方案(WITH cte AS () FROM SELECT (SELECT * FROM cte.rn=1) + ()...
)会生成很多扫描和逻辑读取。
解决方案:1) 表变量 + SELECT @var = @var + Name FROM tbl
:
--Creating the "array"
DECLARE @Array TABLE
(
Idx INT PRIMARY KEY,
Val NVARCHAR(100) NOT NULL
);
WITH Base
AS
(
SELECT Val = t.name,
Idx = ROW_NUMBER() OVER(ORDER BY t.name ASC)
FROM #t t
WHERE t.id between 10 AND 100
)
INSERT @Array (Idx, Val)
SELECT b.Idx, b.Val
FROM Base b;
--Concatenating all names
DECLARE @AllNames NVARCHAR(4000);
--”Reset”/Init @AllNames
SET @AllNames = '';
--String concatenation
SELECT @AllNames = @AllNames + ',' + a.Val
FROM @Array a;
--Remove first char (',')
SELECT @AllNames = STUFF(@AllNames, 1, 1, '');
--The final result
SELECT @AllNames [Concatenating all names - using a table variable];
/*
Concatenating all names - using a table variable
------------------------------------------------
Ami,Bob,Jack,Pete,Steve
*/
--Concatenating Idx=2 and Idx=5
--”Reset” @AllNames value
SET @AllNames = '';
--String concatenation
SELECT @AllNames = @AllNames + ',' + a.Val
FROM @Array a
WHERE a.Idx IN (2,5) --or a.Idx IN (2, (SELECT COUNT(*) FROM @Array))
ORDER BY a.Idx ASC;
--Remove first char (',')
SELECT @AllNames = STUFF(@AllNames, 1, 1, '');
--The final result
SELECT @AllNames [Concatenating Idx=2 and Idx=5 - using a table variable];
/*
Concatenating Idx=2 and Idx=5 - using a table variable
------------------------------------------------------
Bob,Steve
*/
2) 表变量 + PIVOT
:
--Concatenating a finite number of elements (names)
SELECT pvt.[1] + ',' + pvt.[0] AS [PIVOT Concat_1_and_i(0)]
,pvt.[2] + ',' + pvt.[5] AS [PIVOT Concat_2_and_5]
,pvt.*
FROM
(
SELECT a.Idx, a.Val
FROM @Array a
WHERE a.Idx IN (1,2,5)
UNION ALL
SELECT 0, a.Val --The last element has Idx=0
FROM @Array a
WHERE a.Idx = (SELECT COUNT(*) FROM @Array)
) src
PIVOT (MAX(src.Val) FOR src.Idx IN ([1], [2], [5], [0])) pvt;
/*
PIVOT Concat_1_and_i(0) PIVOT Concat_2_and_5
----------------------- --------------------
Ami,Steve Bob,Steve
*/
3) XML + XQuery:
SET ANSI_WARNINGS ON;
GO
DECLARE @x XML;
;WITH Base
AS
(
SELECT Val = t.name,
Idx = ROW_NUMBER() OVER(ORDER BY t.name ASC)
FROM #t t
WHERE t.id BETWEEN 10 AND 100
)
SELECT @x =
(
SELECT b.Idx AS [@Idx]
,b.Val AS [text()]
FROM Base b
FOR XML PATH('Element'), ROOT('Array')
);
/* @x content
<Array>
<Element Idx="1">Ami</Element>
<Element Idx="2">Bob</Element>
<Element Idx="3">Jack</Element>
<Element Idx="4">Pete</Element>
<Element Idx="5">Steve</Element>
</Array>
*/
--Concatenating all names (the result is XML, so a cast is needed)
DECLARE @r XML; --XML result
SELECT @r=@x.query('
(: $e = array element :)
for $e in (//Array/Element)
return string($e)
');
SELECT REPLACE(CONVERT(NVARCHAR(4000), @r), ' ', ',') AS [Concatenating all names - using XML];
/*
Concatenating all names - using XML
-----------------------------------
Ami,Bob,Jack,Pete,Steve
*/
--Concatenating Idx=1 and all names
SELECT @r=@x.query('
(: $e = array element :)
for $e in (//Array/Element[@Idx=1], //Array/Element)
return string($e)
');
SELECT REPLACE(CONVERT(NVARCHAR(4000), @r), ' ', ',') AS [Concatenating Idx=1 and all names - using XML];
/*
Concatenating Idx=1 and all names - using XML
---------------------------------------------
Ami,Ami,Bob,Jack,Pete,Steve
*/
--Concatenating Idx=1 and i(last name)
DECLARE @i INT;
SELECT @r=@x.query('
(: $e = array element :)
for $e in (//Array/Element[@Idx=1], //Array/Element[@Idx=count(//Array/Element)])
return string($e)
');
SELECT REPLACE(CONVERT(NVARCHAR(4000), @r), ' ', ',') AS [Concatenating Idx=1 and i(last name) - using XML];
/*
Concatenating Idx=1 and i(last name) - using XML
------------------------------------------------
Ami,Steve
*/
--Concatenating Idx=2 and Idx=5
SELECT @r=@x.query('
(: $e = array element :)
for $e in (//Array/Element[@Idx=2], //Array/Element[@Idx=5])
return string($e)
');
SELECT REPLACE(CONVERT(NVARCHAR(4000), @r), ' ', ',') AS [Concatenating Idx=2 and Idx=5 - using XML (method 1)];
/*
Concatenating Idx=2 and Idx=5 - using XML (method 1)
----------------------------------------------------
Bob,Steve
*/
--Concatenating Idx=2 and Idx=5
SELECT @x.value('(//Array/Element)[@Idx=2][1]', 'NVARCHAR(100)')
+ ','
+ @x.value('(//Array/Element)[@Idx=5][1]', 'NVARCHAR(100)') AS [Concatenating Idx=2 and Idx=5 - using XML (method 2)];;
/*
Concatenating Idx=2 and Idx=5 - using XML (method 2)
----------------------------------------------------
Bob,Steve
*/
4) 如果问题是如何在 SQL Server 上模拟 ARRAY_AGG
,那么答案可能是:使用 XML。示例:
SET ANSI_WARNINGS ON;
GO
DECLARE @Test TABLE
(
Id INT PRIMARY KEY
,GroupID INT NOT NULL
,Name NVARCHAR(100) NOT NULL
);
INSERT INTO @Test (Id, GroupID, Name)
VALUES
(3 , 1, 'John')
,(5 , 1, 'Mary')
,(8 , 1, 'Michael')
,(13, 1, 'Steve')
,(21, 1, 'Jack')
,(34, 2, 'Pete')
,(57, 2, 'Ami')
,(88, 2, 'Bob');
WITH BaseQuery
AS
(
SELECT a.GroupID, a.Name
FROM @Test a
WHERE a.Id BETWEEN 10 AND 100
)
SELECT x.*
, CONVERT(XML,x.SQLServer_Array_Agg).query
('
for $e in (//Array/Element[@Idx=1], //Array/Element[@Idx=count(//Array/Element)])
return string($e)
') AS [Concat Idx=1 and Idx=i (method 1)]
, CONVERT(XML,x.SQLServer_Array_Agg).query('
let $a := string((//Array/Element[@Idx=1])[1])
let $b := string((//Array/Element[@Idx=count(//Array/Element)])[1])
let $c := concat($a , "," , $b) (: " is used as a string delimiter :)
return $c
') AS [Concat Idx=1 and Idx=i (method 2)]
, CONVERT(XML,x.SQLServer_Array_Agg).query
('
for $e in (//Array/Element[@Idx=(1,count(//Array/Element))])
return string($e)
') AS [Concat Idx=1 and Idx=i (method 3)]
FROM
(
SELECT a.GroupID
,(SELECT ROW_NUMBER() OVER(ORDER BY b.Name) AS [@Idx]
,b.Name AS [text()]
FROM BaseQuery b
WHERE a.GroupID = b.GroupID
ORDER BY b.Name
FOR XML PATH('Element'), ROOT('Array') ) AS SQLServer_Array_Agg
FROM BaseQuery a
GROUP BY a.GroupID
) x;
结果:
GroupID SQLServer_Array_Agg Concat Idx=1 and Idx=i (method 1) Concat Idx=1 and Idx=i (method 2) Concat Idx=1 and Idx=i (method 3)
------- ---------------------------------------------------------------------------------------------------------- --------------------------------- --------------------------------- ---------------------------------
1 <Array><Element Idx="1">Jack</Element><Element Idx="2">Steve</Element></Array> Jack Steve Jack,Steve Jack Steve
2 <Array><Element Idx="1">Ami</Element><Element Idx="2">Bob</Element><Element Idx="3">Pete</Element></Array> Ami Pete Ami,Pete Ami Pete
关于sql-server - SQL Server : collect values in an aggregation temporarily and re-use in the same query,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8109475/
我有一个使用 ARM 模板创建的 python 函数应用程序。当我尝试使用 azure Devops 管道部署函数时,我遇到以下错误, “无法将Web包部署到应用服务。服务暂时不可用代码503” 最佳
如果我在 Python 解释器中创建了一个包含大量进程的池,它显然会出错,但是在这样做之前似乎并没有清理 fork 进程,因此留下了环境脏,系统的其余部分无法 fork 进程。 >>> from mu
我正在构建一个包含 DT 的 UI表格和 slider (均作为输入),以及绘图输出。这些表格用于从多个表格中进行选择。用户只能选择一个单元格进行选择。 我希望用户能够存储表格和 slider 的设置
有没有办法暂时将拆分 Pane 扩展为完整选项卡并在完成后再次返回?我正在寻找一个键盘快捷键来执行此操作。用例是能够根据需要临时切换到全屏。 最佳答案 要最大化事件面板,只需在要扩展的屏幕上 Cmd
我正在开发一个用 PHP 和 Mysqli 编写的复杂数据库应用程序。对于大型数据库操作,我使用后台运行的守护进程(也是 PHP)。在这些可能需要几分钟的操作期间,我想阻止用户访问受影响的数据并向他们
就在几天前,我能够访问我的谷歌电子表格来自一个应用程序(在应用程序引擎中),但今天它坏了。 也就是说,我可以 name= "name of my spreadsheet" self.client =
我开发和维护用 JSP 和 Java 编写的小型内联网 Web 应用程序。它们在 Resin 网络服务器上运行,没有像 Apache 那样的专用 httpd。 在执行维护之前,我激活了一个非常简单的
这是一段代码: public function uploadPhoto(){ $filename = '../storage/temp/image.jpg'; file_put_co
为什么以下代码会在 80% 的时间内打印“read(): Resource temporary unavailable”?那就是EAGAIN代码,和WOULD BLOCK一样,表示没有数据等待读取,但
我正在尝试在 C 的 linux (red-hut) 中创建单线程服务器,它将监听多个套接字。 当我像这样将标志设置为非阻塞时,我需要使用非阻塞套接字: int flagss = fcntl(sock
在网页时出现503 service temporarily unavailable是什么意思?这让很多网友在访问某个网站时摸不着头脑,想看的网页打不开,只能灰溜溜地关闭。而这也对很
最近网站刷新后经常出现503 Service Temporarily Unavailable错误,有时有可以,联想到最近在nginx.conf里做了单ip访问次数限制,(limit_req_zone
我在一个启用了 envers 的项目中创建了一个实体复制器,但是对于这个复制器我不需要审计:有没有办法暂时禁用 envers 审计? 我知道有一些监听器作为拦截器(在审计触发器之前),但我还需要知道审
我有 apache 坐在我的节点服务器前面。节点在某个端口上运行,我使用 apache 代理到该端口,并且还为 https 配置了 apache。 当我启动 apache 然后启动我的节点服务器时,一
Sequelize.js 有没有办法暂时禁用时间戳,最好是单个查询? 特别是,我正在运行一个查询 MyModel.update({ UserId: 1 }, { where: {
我尝试在本地开发系统上设置 Varnish ,但它在启动后几秒钟终止,并显示以下消息: varnishd -s malloc,1G -T 127.0.0.1:2000 -a 0.0.0.0:81 -F
(在 Azure 门户中报告支持问题时,似乎没有选择 Application Insights 的选项,因此发布了这篇文章) 在大约 12 小时内,当我尝试查看特定应用服务的 Application
供引用: 我在 docker desktop for mac 上运行 Kubernetes 基于Nginx镜像的网站 我在 Kubetesetes 上运行 2 个简单的网站部署并使用 NodePort
(在 Azure 门户中报告支持问题时,似乎没有选择 Application Insights 的选项,因此发布了这篇文章) 在大约 12 小时内,当我尝试查看特定应用服务的 Application
编辑: 我正在以矩阵乘法为例学习多线程,我创建了这个程序: #include #include #include #include using namespace std; int N = 5
我是一名优秀的程序员,十分优秀!