我发现UNPIVOT能够自动排除具有NULL值的字段.但是,CROSS APPLY-VALUES方法无法做到这一点.有谁知道如何自动从CROSS APPLY-VALUES中排除NULL值字段?假设,如果字段Field3和Field4包含NULL值,则将其排除.
SELECT
E.FieldA,
E.FieldB,
E.FieldC,
DBParam.Display,
DBParam.Value
INTO DBParam
FROM
Map_Data AS E
CROSS APPLY (VALUES (Field1, 'Field1'),
(Field2, 'Field2'),
(Field3, 'Field3'),
(Field4, 'Field4')
) AS DBParam(Value, Display)
Run Code Online (Sandbox Code Playgroud) 有一个简单的代码。我一直以为ROW_NUMBER外部和CROSS APPLY子句中的那个都应该生成相同的输出(在我的示例中,我例外rn = crn)。你能解释为什么不是那样吗?
CREATE TABLE #tmp ( id INT, name VARCHAR(200) );
INSERT INTO #tmp
VALUES ( 1, 'a' ),
( 2, 'a' ),
( 3, 'a' ),
( 4, 'b' ),
( 5, 'b' ),
( 6, 'c' ),
( 7, 'a' );
SELECT name,
ROW_NUMBER() OVER ( PARTITION BY name ORDER BY id ) AS rn,
a.crn
FROM #tmp
CROSS APPLY (
SELECT ROW_NUMBER() OVER ( PARTITION BY name ORDER BY id ) AS crn
) a; …Run Code Online (Sandbox Code Playgroud) t-sql sql-server sql-server-2008 sql-server-2008-r2 cross-apply
我有这样一张桌子:
account | check1 | check2
1 | 100]200]300 | 101]209]305
2 | 401]502 | 404]511
3 | 600 | 601
Run Code Online (Sandbox Code Playgroud)
我想将记录分成这样的东西:
account | check1 | check2
1 | 100 | 101
1 | 200 | 209
1 | 300 | 305
2 | 401 | 404
2 | 502 | 511
. | . | .
. | . | .
. | . | .
Run Code Online (Sandbox Code Playgroud)
如何仅使用SQL Server执行此操作?
谢谢,
我刚刚发现了CROSS APPLY运算符,并给人以印象,它在处理派生列进行计算时非常有用。
因此,我尝试了以下方法:
SELECT leadYear,TotalLeadsCalled,SuccessLeadsCalled,SuccessLeadsPercent
FROM dbo.tblBinOutboundCallActivity
CROSS APPLY(VALUES (YEAR(leadactivitydate))) AS a1(leadyear)
CROSS APPLY(VALUES (COUNT(leadStatusID))) AS a2(TotalLeadsCalled)
CROSS APPLY(VALUES (COUNT(CASE WHEN leadStatusID = 2 THEN 1 ELSE NULL END))) AS a3(SuccessLeadsCalled)
CROSS APPLY(VALUES (SUM((SuccessLeadsCalled/TotalLeadsCalled)*100))) AS a4(SuccessLeadsPercent)
GROUP BY leadYear
Run Code Online (Sandbox Code Playgroud)
但是我收到以下错误:
APPLY右侧的聚合不能引用左侧的列。
我不太了解该错误,尤其是在第一个交叉应用实际上是孤立运行的情况下。我只是对概念完全错误了吗?
我有一位同事喜欢使用她所说的“逗号连接”。我最近在现场环境中第一次使用了交叉应用,并注意到它给出了与她的“逗号连接”相同的结果,并且想知道两者是否有什么不同,或者她的方式是否只是速记。下面我有代码创建两个临时表,然后进行交叉应用,将第一个临时表中的所有内容附加到第二个临时表中的所有内容。它还通过她的“逗号连接”来实现这一点。
Select
'a' as a,'b' as b,'c' as c,'d' as d
Into #letter
Create table #name
( name varchar(10))
Insert Into #Name
Values('David'),('Kai'),('Brad'),('Todd'),('Vivian')
Select *
From #Name
Cross apply(Select * from #letter) as A
Select *
From #name
,#letter
Run Code Online (Sandbox Code Playgroud)
那么这些是相同的只是不同的编写方式还是在某些情况下会做不同的事情?哦,我们使用 SQL 2012。
大多数讨论的在线文档或教程都OUTER|CROSS APPLY描述了如下内容:
SELECT columns\nFROM table OUTER|CROSS APPLY (SELECT \xe2\x80\xa6 FROM \xe2\x80\xa6);\nRun Code Online (Sandbox Code Playgroud)\n\n子查询通常是完整SELECT \xe2\x80\xa6 FROM \xe2\x80\xa6查询。
我一定在某处读过,子查询不需要\xe2\x80\x99t,FROM 在这种情况下,列似乎来自主查询:
SELECT columns\nFROM table OUTER|CROSS APPLY (SELECT \xe2\x80\xa6 );\nRun Code Online (Sandbox Code Playgroud)\n\n因为我经常使用它作为预计算列的方法。
\n\n问题是如果子FROM查询中省略了 ,到底会发生什么?是其他东西的缩写吗?我发现它和主表中的意思不一样。
微软 SQL Server Management Studio v18.8
我有一个表,其中有不同的列和列名称。我需要对数据进行逆透视,以便最终可以将其存储到另一个表中。不幸的是,这是一个过程,因为原始表格是从 Google 表格中提取的。
我在这里查找了几篇文章和答案,但无法成功复制其中任何一篇。我需要根据项目、时间戳和位置进行逆透视。那么 Q1、Q2、Q3 等应该不旋转。下面是一个示例表和查询,它将获得我想要的结果。任何在动态 SQL 中获取此信息以便将来添加/修改列的帮助将不胜感激。我愿意使用 UNPIVOT 或任何其他功能来获得所需的结果。实际的数据源将是永久表,而不是临时表。
创建表
DROP TABLE IF EXISTS #test
CREATE TABLE #test (Item VARCHAR(16), Timestamp DATETIME, Location VARCHAR(2), Q1 VARCHAR(3), Q2 VARCHAR(3), Q3 VARCHAR(3))
INSERT INTO #test VALUES('Stapler','2021-04-14 12:00:00.000', 'US','Yes','No','Yes'),
('Paper','2021-04-10 16:00:00.000', 'CA','No','Yes','Yes'),
('Pen','2021-04-06 15:00:00.000','MX','Yes','Yes','No')
Run Code Online (Sandbox Code Playgroud)
使用交叉应用取消透视
SELECT A.Item,
A.Timestamp,
A.Location,
B.*
FROM #test AS A
CROSS APPLY
(
VALUES ('Q1', A.Q1),
('Q2', A.Q2),
('Q3', A.Q3)
) B (Question,Answer)
Run Code Online (Sandbox Code Playgroud) 我有以下XML:
<root>
<row value="US">
<col value="00">Jon</col>
<col value="01">David</col>
<col value="02">Mike</col>
<col value="03">Nil</col>
</row>
<row value="Canada">
<col value="C1">Pollard</col>
</row>
<row value="Japan">
<col value="J1">Yin</col>
<col value="J2">Li</col>
</row>
<row value="India">
<col value="MP">Ram</col>
<col value="UP">Paresh</col>
<col value="AP">Mohan</col>
</row>
</root>
Run Code Online (Sandbox Code Playgroud)
我希望通过使用SQL Server查询以下输出:
US 00 Jon
US 01 David
US 02 Mike
US 03 Nil
Canada C1 Pollard
Japan J1 Yin
Japan J2 Li
India MP Ram
India UP Paresh
India AP Mohan
Run Code Online (Sandbox Code Playgroud)
我正在使用以下SQL查询:
declare @x xml
set @x =
'<root>
<row value="US">
<col value="00">Jon</col>
<col …Run Code Online (Sandbox Code Playgroud) 以下查询给出了缺少的关键字错误..
select *
from its_account aac
CROSS APPLY its.fnGetAccountIdentifier(aac.account_key) ;
Run Code Online (Sandbox Code Playgroud)
这是我的功能:
create or replace FUNCTION fnGetAccountIdentifier
(
v_AccountKey IN NUMBER
)
RETURN fnGetAccountIdentifier_pkg.tt_fnGetAccountIdentifier_type PIPELINED
AS
v_temp SYS_REFCURSOR;
v_temp_1 TT_FNGETACCOUNTIDENTIFIER%ROWTYPE;
BEGIN
OPEN v_temp FOR
SELECT *
FROM tt_fnGetAccountIdentifier;
LOOP
FETCH v_temp INTO v_temp_1;
EXIT WHEN v_temp%NOTFOUND;
PIPE ROW ( v_temp_1 );
END LOOP;
END;
Run Code Online (Sandbox Code Playgroud)
我不知道我在哪里做错了.我真的很陌生.
虽然转置单列非常简单,但我需要转置大量数据,其中需要转置 3 组、10 多个相关列。
create table test
(month int,year int,po1 int,po2 int,ro1 int,ro2 int,mo1 int,mo2 int, mo3 int);
insert into test
values
(5,2013,100,20,10,1,3,4,5),(4,2014,200,30,20,2,4,5,6),(6,2015,200,80,30,3,5,6,7) ;
select * FROM test;
Run Code Online (Sandbox Code Playgroud)
给出
| 月 | 年 | 波1 | 氧分压 | 罗1 | 罗2 | 莫1 | 钼 | 莫3 |
|---|---|---|---|---|---|---|---|---|
| 5 | 2013年 | 100 | 20 | 10 | 1 | 3 | 4 | 5 |
| 4 | 2014年 | 200 | 30 | 20 | 2 | 4 | 5 | 6 |
| 6 | 2015年 | 200 | 80 | 30 | 3 | 5 | 6 | 7 |
使用 UNPIVOT 转置
select
month, year,
PO, RO, MO
from ( SELECT * from test) …Run Code Online (Sandbox Code Playgroud) 我有一个查询,我认为使用交叉申请会更有效.我已经将语法从连接更改为交叉应用,但我收到了一般语法错误:
消息170,级别15,状态1,行14行14:"应用"附近的语法不正确.Msg 156,Level 15,State 1,Line 21关键字'as'附近的语法不正确.
这是我第一次使用交叉应用,我没有看到语法错误(至少在与我发现的示例比较时).这是代码:
Select v.PC_ID
, v.PC_Name
, v.LOB
, v.REG
, v.DST
, v.PC
, d.Effective_Date as DateOfLastInc
, p.TotalPriceIncPct
, p.last_update_by
, d.PlanEffective_Date
, p2.PlanTotalPriceIncPct
--INTO #temp1
from v_PC_Profile v
cross apply (
Select pc_id
, Effective_Date=max(Effective_Date)
, PlanEffective_Date=max(PlanEffective_Date)
from dbo.Price_Inc_PC_Details
where pc_id = v.pc_id
group by pc_id
) as d --on d.PC_ID=v.PC_ID
left join dbo.Calendar c on c.FULL_DATE=d.Effective_Date
left join dbo.Price_Inc_PC_Details p on d.PC_ID=p.PC_ID and d.Effective_Date=p.Effective_Date
left join dbo.Price_Inc_PC_Details p2 on d.PC_ID=p2.PC_ID and …Run Code Online (Sandbox Code Playgroud) 我有Car车ID的表(smallint)和另一张表与每辆车相关的事件.
现在我想获得按特定标准选择的汽车的最新活动,但这似乎不起作用.
当我有这样的查询来获取每辆车的最新事件时,它可以正常工作:
SELECT * FROM [dvm_data].[dbo].[Car] CD
CROSS APPLY (
SELECT TOP 1 * FROM [dvm_data].[dbo].[CarData] WHERE CarIndex = CD.ID) MD
Run Code Online (Sandbox Code Playgroud)
在另一方面,当我尝试使用限制汽车WHERE在第一SELECT,它不再起作用:
SELECT * FROM [dvm_data].[dbo].[Car] WHERE ID > 100 CD
CROSS APPLY (
SELECT TOP 1 * FROM [dvm_data].[dbo].[CarData] WHERE CarIndex = CD.ID) MD
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我收到错误消息:
消息102,级别15,状态1,行1'CD'附近的语法不正确.消息102,级别15,状态1,行3'MD'附近的语法不正确.
第一个查询本身工作正常:
SELECT * FROM [dvm_data].[dbo].[Car] WHERE ID > 100
Run Code Online (Sandbox Code Playgroud)
我在这里缺少什么?通常使用的例子CROSS APPLY没有WHERE在第一SELECT查询,这是否意味着什么?
另一件事,如果我想DISTINCT在第一次查询中使用,找到具有某种类型事件的汽车,然后找到这些汽车的最新事件.它会是这样的,但这也行不通:
SELECT DISTINCT ID FROM …Run Code Online (Sandbox Code Playgroud) 我读过的大多数文档都表明,CROSS APPLY 的行为方式与 INNER JOIN 类似,只有在两个源表中都有匹配的行时,行才会包含在输出中。
然而,情况似乎并不总是如此,例如,如果您运行以下 SQL 查询,结果将包含 3 行,其中一行包含许多 NULL,因为右侧表中没有行:
CREATE TABLE #Order
(
Id int PRIMARY KEY
)
CREATE TABLE #OrderItem
(
OrderId int NOT NULL,
Price decimal(18, 2) NOT NULL
)
INSERT INTO #Order
VALUES(1), (2), (3)
INSERT INTO #OrderItem
VALUES(1, 10), (1, 20), (3,100)
SELECT *
FROM #Order o
CROSS APPLY
(
SELECT SUM(Price) AS TotalPrice, COUNT(*) AS Items, MIN(Price) AS MinPrice
FROM #OrderItem
WHERE OrderId = o.Id
) t
DROP TABLE #Order
DROP TABLE …Run Code Online (Sandbox Code Playgroud)