在东西中应用排序,东西不同并按以下顺序排序
apply sorting in stuff, stuff distinct and order by
我需要使用 STUFF 运算符将具有相同值的行合并为一个。我存档了行连接,但值的顺序不正确。
http://www.sqlfiddle.com/#!18/2f420/1/0
正如您在结果 window 中看到的那样,TypeB 在 TypeA 旁边,但是 Amount 值的序列与 Type 值不对应,其中 0.09K 应该在 3k 旁边
如何制作不同值的STUFF并保存序列(按rn排序)?
create table SomeTable (Code int, Type nvarchar(50), Amount nvarchar(50), Date datetime);
insert into SomeTable VALUES(20, 'TypeA', '12k', cast('01/01/2019' as datetime));
insert into SomeTable VALUES(20, 'TypeA', '11k', cast('01/01/2018' as datetime));
insert into SomeTable VALUES(22, 'TypeA', '17k', cast('01/02/2017' as datetime));
insert into SomeTable VALUES(22, 'TypeA', '17k', cast('01/01/2017' as datetime));
insert into SomeTable VALUES(25, 'TypeB', '0.09k', cast('01/02/2019' as datetime));
insert into SomeTable VALUES(25, 'TypeA', '3k', cast('01/01/2019' as datetime));
with t as (
select
row_number() over(partition by st.Code order by st.Date) as rn,
st.Code,
st.Type,
st.Amount,
st.Date
from SomeTable st
)
select
t1.Code,
stuff((select distinct ',' + t.Type from t
where t.Code = t1.Code
for XML path('')), 1,1, '') as Type,
stuff((select distinct ',' + t.Amount from t
where t.Code = t1.Code
for XML path('')), 1,1, '') as Amount,
t1.Date
from t as t1
where t1.rn = 1
order by t1.Date
将 order by 放入 stuff 段:
select
t1.Code,
stuff((select distinct top 100 percent ',' + t.Type from t
where t.Code = t1.Code order by ',' + t.Type
for XML path('')), 1,1, '') as Type,
stuff((select distinct ',' + t.Amount from t
where t.Code = t1.Code
for XML path('')), 1,1, '') as Amount,
t1.Date
from t as t1
where t1.rn = 1
order by t1.Date
这样试试怎么样?
with t as (
select
row_number() over(partition by st.Code order by st.Date) as rn,
st.Code,
st.Type,
st.Amount,
st.Date
from SomeTable st
),
t2 as (
select distinct top 100 percent
st.code,
st.type,
st.amount
from SomeTable st
order by st.code, st.type, st.amount
)
select
t1.Code,
stuff((select distinct ',' + t2.Type from t2
where t2.Code = t1.Code
for XML path('')), 1,1, '') as Type,
stuff((select ',' + t2.Amount from t2
where t2.Code = t1.Code
for XML path('')), 1,1, '') as Amount,
t1.Date
from t as t1
where t1.rn = 1
order by t1.Date
对 SQL 中的任何结果应用排序是通过使用 order by
子句完成的。
给您带来困难的不是 stuff
函数,而是您没有为子查询指定 order by
的事实。
如果没有 and order by
子句,子查询 returns 以任意顺序记录 - 这就是为什么你得到现在得到的结果。
但是请注意,由于结果的顺序是任意的,您下次 运行 查询时可能会得到不同的结果。
因此,您必须在生成 C.S.V 列的子查询中指定一个 order by
子句。
现在我不太确定你期望的顺序是什么,但它可能是按 rn
或 rn desc
排序(根据图像我认为它是第一个)。
然而,这里有一个技巧——因为你想要 type
和 amount
的不同值,你不能简单地在 order by
子句中使用 rn
- SQL 服务器将引发以下错误:
ORDER BY items must appear in the select list if SELECT DISTINCT is specified.
所以,诀窍是不要使用 distinct
,而是使用 group by
,而不是在 order by
子句中使用 rn
,而是 max(rn)
.这样,您将获得 TypeA,TypeB
和 3k,0.09k
- 并且它们将是一致的。
说了这么多 - 这是您的代码的修订版本(cte 保持不变):
select t1.Code,
stuff((
select ','+ t.Type
from t
where t.Code = t1.Code
group by t.Type
order by max(rn)
for XML path('')
), 1,1, '') as Type,
stuff((select ',' + t.Amount
from t
where t.Code = t1.Code
group by t.Amount
order by max(rn)
for XML path('')), 1,1, '') as Amount,
t1.Date
from t as t1
where t1.rn = 1
order by t1.Date
结果:
Code Type Amount Date
22 TypeA 17k 2017-01-01
20 TypeA 11k,12k 2018-01-01
25 TypeA,TypeB 3k,0.09k 2019-01-01
注意 (我现在才看到)有一个非常有效的观点 - distinct
可能根本不是一个好的选择.
在您有 TypeA, TypeB, TypeA
且相应金额 10K, 11K, 12K
-
的情况下
如果您执行 distinct,结果将是 TypeA, TypeB
和金额 10K, 11K, 12K
- 并且无法分辨哪个金额属于哪种类型。
我需要使用 STUFF 运算符将具有相同值的行合并为一个。我存档了行连接,但值的顺序不正确。
http://www.sqlfiddle.com/#!18/2f420/1/0
正如您在结果 window 中看到的那样,TypeB 在 TypeA 旁边,但是 Amount 值的序列与 Type 值不对应,其中 0.09K 应该在 3k 旁边
如何制作不同值的STUFF并保存序列(按rn排序)?
create table SomeTable (Code int, Type nvarchar(50), Amount nvarchar(50), Date datetime);
insert into SomeTable VALUES(20, 'TypeA', '12k', cast('01/01/2019' as datetime));
insert into SomeTable VALUES(20, 'TypeA', '11k', cast('01/01/2018' as datetime));
insert into SomeTable VALUES(22, 'TypeA', '17k', cast('01/02/2017' as datetime));
insert into SomeTable VALUES(22, 'TypeA', '17k', cast('01/01/2017' as datetime));
insert into SomeTable VALUES(25, 'TypeB', '0.09k', cast('01/02/2019' as datetime));
insert into SomeTable VALUES(25, 'TypeA', '3k', cast('01/01/2019' as datetime));
with t as (
select
row_number() over(partition by st.Code order by st.Date) as rn,
st.Code,
st.Type,
st.Amount,
st.Date
from SomeTable st
)
select
t1.Code,
stuff((select distinct ',' + t.Type from t
where t.Code = t1.Code
for XML path('')), 1,1, '') as Type,
stuff((select distinct ',' + t.Amount from t
where t.Code = t1.Code
for XML path('')), 1,1, '') as Amount,
t1.Date
from t as t1
where t1.rn = 1
order by t1.Date
将 order by 放入 stuff 段:
select
t1.Code,
stuff((select distinct top 100 percent ',' + t.Type from t
where t.Code = t1.Code order by ',' + t.Type
for XML path('')), 1,1, '') as Type,
stuff((select distinct ',' + t.Amount from t
where t.Code = t1.Code
for XML path('')), 1,1, '') as Amount,
t1.Date
from t as t1
where t1.rn = 1
order by t1.Date
这样试试怎么样?
with t as (
select
row_number() over(partition by st.Code order by st.Date) as rn,
st.Code,
st.Type,
st.Amount,
st.Date
from SomeTable st
),
t2 as (
select distinct top 100 percent
st.code,
st.type,
st.amount
from SomeTable st
order by st.code, st.type, st.amount
)
select
t1.Code,
stuff((select distinct ',' + t2.Type from t2
where t2.Code = t1.Code
for XML path('')), 1,1, '') as Type,
stuff((select ',' + t2.Amount from t2
where t2.Code = t1.Code
for XML path('')), 1,1, '') as Amount,
t1.Date
from t as t1
where t1.rn = 1
order by t1.Date
对 SQL 中的任何结果应用排序是通过使用 order by
子句完成的。
给您带来困难的不是 stuff
函数,而是您没有为子查询指定 order by
的事实。
如果没有 and order by
子句,子查询 returns 以任意顺序记录 - 这就是为什么你得到现在得到的结果。
但是请注意,由于结果的顺序是任意的,您下次 运行 查询时可能会得到不同的结果。
因此,您必须在生成 C.S.V 列的子查询中指定一个 order by
子句。
现在我不太确定你期望的顺序是什么,但它可能是按 rn
或 rn desc
排序(根据图像我认为它是第一个)。
然而,这里有一个技巧——因为你想要 type
和 amount
的不同值,你不能简单地在 order by
子句中使用 rn
- SQL 服务器将引发以下错误:
ORDER BY items must appear in the select list if SELECT DISTINCT is specified.
所以,诀窍是不要使用 distinct
,而是使用 group by
,而不是在 order by
子句中使用 rn
,而是 max(rn)
.这样,您将获得 TypeA,TypeB
和 3k,0.09k
- 并且它们将是一致的。
说了这么多 - 这是您的代码的修订版本(cte 保持不变):
select t1.Code,
stuff((
select ','+ t.Type
from t
where t.Code = t1.Code
group by t.Type
order by max(rn)
for XML path('')
), 1,1, '') as Type,
stuff((select ',' + t.Amount
from t
where t.Code = t1.Code
group by t.Amount
order by max(rn)
for XML path('')), 1,1, '') as Amount,
t1.Date
from t as t1
where t1.rn = 1
order by t1.Date
结果:
Code Type Amount Date
22 TypeA 17k 2017-01-01
20 TypeA 11k,12k 2018-01-01
25 TypeA,TypeB 3k,0.09k 2019-01-01
注意 distinct
可能根本不是一个好的选择.
在您有 TypeA, TypeB, TypeA
且相应金额 10K, 11K, 12K
-
的情况下
如果您执行 distinct,结果将是 TypeA, TypeB
和金额 10K, 11K, 12K
- 并且无法分辨哪个金额属于哪种类型。