应用分类,分类和顺序排序

时间:2019-06-17 07:31:24

标签: sql sql-server tsql sql-server-2008

我需要使用STUFF运算符将具有相同值的行合并为一个。我存档了行串联,但是值顺序不正确。

http://www.sqlfiddle.com/#!18/2f420/1/0

在结果窗口中看到,TypeB在TypeA旁边,但是Amount值序列与Type值不对应,其中0.09K应该在3k后面

enter image description here

如何使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

3 个答案:

答案 0 :(得分:1)

将订单放入物料段:

let businessesJSON = try JSONDecoder().decode(Businesses.self, from: data)
self.businesses = businessesJSON
self.tableView.reloadData()

答案 1 :(得分:1)

这样尝试如何?

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

答案 2 :(得分:1)

使用order by子句对SQL中的任何结果应用排序。
不是stuff函数会给您带来麻烦,而是事实是您没有为子查询指定order by
如果不使用and order by子句,则子查询将以任意顺序返回记录-这就是为什么要得到现在得到的结果的原因。 但是请注意,由于结果的顺序是任意的,因此下次运行查询时可能会得到不同的结果。

因此,必须在子查询中指定一个生成C.S.V列的order by子句。

现在我不太确定您期望的顺序是什么,但是它可能是按rnrn desc排序(基于我认为是第一张图片)。
但是,这里有一个窍门-因为您想要typeamount的不同值,所以不能简单地在rn子句中使用order by-SQL Server将引发以下错误:

  如果指定了SELECT DISTINCT,则

ORDER BY项目必须出现在选择列表中。

因此,诀窍是不使用distinct,而是使用group by,而不要在rn子句中使用order by,而要使用max(rn) 。这样,您将得到TypeA,TypeB3k,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

注意 Salman's comment to the question(我现在才看到)非常重要-distinct可能根本不是一个好选择。
在您有TypeA, TypeB, TypeA和相应金额10K, 11K, 12K的情况下-
如果您进行区分,则结果将是TypeA, TypeB和数量10K, 11K, 12K-并且将无法确定哪个数量属于哪种类型。