选择多个列到一个字符串(按日期)

时间:2018-05-29 13:30:36

标签: sql sql-server

我的价格表看起来像这样:

Effect

我想查询结果如下:

public static class Effect
{
    public static void ExpireTemporaryEffects(IEffectStorage effectStorage)
    {
        effectStorage.AllEffects.ForEach(effectSet =>
        {
            var effects = effectSet.ToList();
            effects.ForEach(effect =>
            {
                if(effect is ITemporaryEffect) {
                    effect.TimeRemaining--;
                    if(effect.TimeRemaining <= 0) {
                        effectSet.Remove(effect);
                    }
                }
            });
        });
    }
}

因此,应列出所有不同的供应商及其价格,并且仅按日期排列。 我到目前为止:

   ItemCode VendorCode  UnitCost    StartingDate    
   333       362         2.31       2016-08-19 00:00:00.0
   333       362         2.16       2018-02-22 00:00:00.0
   444       362        12.96       2014-01-09 00:00:00.0   
   444       362        13.10       2015-01-09 00:00:00.0
   444       430        13.05       2017-04-01 00:00:00.0
   444       550        13.30       2018-02-01 00:00:00.0

但是甚至没有接近我需要的结果。

4 个答案:

答案 0 :(得分:1)

尝试使用此查询:

{{1}}

答案 1 :(得分:1)

我会使用row_number()函数:

select concat(itemcode, ':', 
       stuff( ( select top (1) with ties ',(' +concat(VendorCode, ',', UnitCost ,',', cast(StartingDate as date)) +')'
                from Pricelist
                where itemcode = p.itemcode
                order by row_number() over (partition by VendorCode order by StartingDate desc)
                for xml path('')
               ), 1, 1, ''
            ))
from Pricelist p
group by itemcode;

答案 2 :(得分:1)

首先对项目代码进行分组,然后将其链接到包含供应商详细信息的字符串,这可能非常有效。

将这些项目代码链接到带有FOR XML的OUTER APPLY很有效。

例如:

declare @Pricelist table (ItemCode int, VendorCode int, UnitCost decimal (10,2), StartingDate datetime)

insert into @Pricelist values
(333,362,02.31,'2016-08-19T00:01:00'),
(333,362,02.16,'2018-02-22T00:02:00'),
(444,362,12.96,'2014-01-09T00:03:00'),  
(444,362,13.10,'2015-01-09T00:04:00'),
(444,430,13.05,'2017-04-01T00:05:00'),
(444,550,13.30,'2018-02-01T00:06:00');

select concat(itemcode,':',stuff(x.details,1,1,'')) as ItemVendorDetails
from (select distinct itemcode from @Pricelist) i
outer apply 
(
    select top 1 with ties 
    concat(',(',VendorCode,',',UnitCost,',',convert(date,StartingDate),')')
    from @Pricelist p
    where p.ItemCode = i.ItemCode
    order by row_number() over (partition by ItemCode, VendorCode order by StartingDate desc)
    for xml path('')
) x(details);

结果:

ItemVendorDetails
------------------------------------------------------------------------
333:(362,2.16,2018-02-22)
444:(362,13.10,2015-01-09),(430,13.05,2017-04-01),(550,13.30,2018-02-01)

答案 3 :(得分:0)

以下查询适用于提供的示例数据:

;WITH VendorPerItemCTE AS (
   SELECT ItemCode,
          VendorCode,
          UnitCost,
          StartingDate,
          ROW_NUMBER() OVER (PARTITION BY ItemCode, VendorCode 
                             ORDER BY StartingDate DESC) AS seq
  FROM PriceList
)      
SELECT CAST(ItemCode AS VARCHAR(12)) + ':' + STUFF(ItemData , 1, 1, '')
FROM (
   SELECT DISTINCT p.ItemCode,
          (SELECT ', (' + CAST(VendorCode AS VARCHAR(10)) + ', ' + 
                        CAST(UnitCost AS VARCHAR(10)) + ', ' + 
                        CONVERT(VARCHAR(12), StartingDate, 102 ) +
                  ')'
          FROM VendorPerItemCTE AS c
          WHERE p.ItemCode = c.ItemCode AND c.seq = 1      
          FOR XML PATH('')) AS ItemData
   FROM PriceList AS p) AS t

Demo here