使用大小写和定界符获取字段数据

时间:2018-09-20 07:37:57

标签: sql-server

我不知道我的问题是否正确,但是我已经尝试通过Google搜索有关此问题的信息,但似乎无法回答我的问题。我要做的就是计算每个代理的违规情况。

违规行为:早期帕克,晚期帕克,加固

我的桌子看起来像这样。

|Date       | Agent     | Violation    |
+-----------+-----------+--------------+
|08/10/2019 | John Doe  | Early Parker |
+-----------+-----------+--------------+
|08/10/2019 | Alex Gee  | Late Parker  |
+-----------+-----------+--------------+
|08/11/2019 | John Doe  | Reinforcement|
+-----------+-----------+--------------+
|08/11/2019 | John Doe  | Early Parker |
+-----------+-----------+--------------+
|08/12/2019 | Matt Hill | Late Parker  |
+-----------+-----------+--------------+

因此,当我用此代码计算每次代理违规时:

ts.Date as [Date],
ts.Agent as [Agent],
count(Case when ts.Remarks = 'Early Parker' then ts.Remarks END) as [Early Parker],

count(Case when ts.Remarks = 'Late Parker' then ts.Remarks END) as [Late Parker],

count(Case when ts.Remarks = 'Reinforcement' then ts.Remarks END) as [Reinforcement]

我的桌子现在看起来像这样,可以正常工作:

|Date       | Agent     | Early Parker | Late Parker | Reinforcement |
+-----------+-----------+--------------+-------------+---------------+
|08/10/2019 | John Doe  | 1            | 0           | 0             |
+-----------+-----------+--------------+-------------+---------------+
|08/10/2019 | Alex Gee  | 0            | 1           | 0             |
+-----------+-----------+--------------+-------------+---------------+
|08/11/2019 | John Doe  | 0            | 0           | 1             |
+-----------+-----------+--------------+-------------+---------------+
|08/12/2019 | Matt Hill | 0            | 1           | 0             |
+-----------+-----------+--------------+-------------+---------------+

我的问题是,如果“备注”列包含2个或更多违规怎么办? 喜欢

|Date       | Agent     | Violation                  |
+-----------+-----------+----------------------------+
|08/10/2019 | John Doe  | Early Parker; Late Parker  |
+-----------+-----------+----------------------------+
|08/10/2019 | Alex Gee  | Late Parker                |
+-----------+-----------+----------------------------+
|08/11/2019 | John Doe  | Reinforcement; Late Parker |
+-----------+-----------+----------------------------+
|08/11/2019 | John Doe  | Early Parker               |
+-----------+-----------+----------------------------+
|08/12/2019 | Matt Hill | Late Parker; Reinforcement |
+-----------+-----------+----------------------------+

现在桌子应该看起来像这样

|Date       | Agent     | Early Parker | Late Parker | Reinforcement |
+-----------+-----------+--------------+-------------+---------------+
|08/10/2019 | John Doe  | 1            | 2           | 0             |
+-----------+-----------+--------------+-------------+---------------+
|08/10/2019 | Alex Gee  | 0            | 1           | 0             |
+-----------+-----------+--------------+-------------+---------------+
|08/11/2019 | John Doe  | 1            | 1           | 1             |
+-----------+-----------+--------------+-------------+---------------+
|08/12/2019 | Matt Hill | 0            | 1           | 1             |
+-----------+-----------+--------------+-------------+---------------+

我该如何实现?有什么帮助吗?

3 个答案:

答案 0 :(得分:0)

您需要使用带分隔符的分隔符,例如DelimitedSplit8K

SELECT t.Date, t.Agent,
       count(Case when s.Item = 'Early Parker'  then s.Item END) as [Early Parker],
       count(Case when s.Item = 'Late Parker'   then s.Item END) as [Late Parker],
       count(Case when s.Item = 'Reinforcement' then s.Item END) as [Reinforcement]
FROM   yourtable t
       CROSS APPLY DelimitedSplit8K ( t.Remarks , ',' ) s
GROUP BY t.Date, t.Agent

答案 1 :(得分:0)

您的预期输出需要更正,即Late ParkerJohn Doe违反08/10/2019的计数为ONE。如果我理解正确,那么您将从以下查询中获得预期的输出。

create table #v (Date       date, Agent     varchar(10), Violation   varchar(100))

insert #v values
 ('08/10/2019','John Doe','Early Parker; Late Parker ') 
,('08/10/2019','Alex Gee','Late Parker ')
,('08/11/2019','John Doe','Reinforcement; Late Parker ')
,('08/11/2019','John Doe','Early Parker')
,('08/12/2019','Matt Hil','Late Parker; Reinforcement')

select * from #v

select date,Agent, 
  count(case when col.value('.', 'varchar(max)')  = 'Early Parker' then 1 end )'Early Parker'
, count(case when col.value('.', 'varchar(max)')  = 'Late Parker ' then 1 end )'Late Parker '
, count(case when col.value('.', 'varchar(max)')  = 'Reinforcement' then 1 end) 'Reinforcement'
from (
select date,Agent
, convert(xml, '<x>'+REPLACE(Violation, '; ', '</x><x>')+'</x>') b from #v 
) a
cross apply b.nodes('/x') as x(col)
group by date, Agent

输出:

   date       Agent   Early Parker  Late Parker     Reinforcement
2019-08-10  Alex Gee       0            1                 0
2019-08-10  John Doe       1            1                 0
2019-08-11  John Doe       1            1                 1
2019-08-12  Matt Hil       0            1                 1

答案 2 :(得分:0)

另一个解决方案是:

    Declare @YourTable table (Date smalldatetime,Agent varchar(50),Violation varchar(50))
    Insert Into @YourTable values
    ('2019-08-10','John Doe','Early Parker; Late Parker'),
    ('2019-08-10','Alex Gee','Late Parker'),
    ('2019-08-11','John Doe','Reinforcement;Late Parker'),
    ('2019-08-11','John Doe','Early Parker'),
    ('2019-08-12','Matt Hill','Reinforcement;Late Parker'),

    ('2019-08-13','Donald','Reinforcement;Late Parker'),
    ('2019-08-13','Donald','Reinforcement;Early Parker'),
    ('2019-08-13','Jake','Early Parker; Reinforcement'),
    ('2019-08-13','Jake','Reinforcement;Early Parker')

    SELECT t.Date, t.Agent,
    SUM(CASE WHEN CHARINDEX('Early Parker',t.Violation,0 )>=1 THEN 1 ELSE 0 END ) as [Early Parker],
    SUM(CASE WHEN CHARINDEX('Late Parker',t.Violation,0 )>=1 THEN 1 ELSE 0 END ) as [Late Parker],
    SUM(CASE WHEN CHARINDEX('Reinforcement',t.Violation,0 )>=1 THEN 1 ELSE 0  END ) as [Reinforcement]

    FROM @YourTable t  
    group by
    t.Date, t.Agent
    ORDER BY
    t.Date, t.Agent

结果:

    Date                Agent       Early Parker  Late Parker  Reinforcement
    2019-08-10 00:00:00 Alex Gee    0               1           0
    2019-08-10 00:00:00 John Doe    1               1           0
    2019-08-11 00:00:00 John Doe    1               1           1
    2019-08-12 00:00:00 Matt Hill   0               1           1
    2019-08-13 00:00:00 Donald      1               1           2
    2019-08-13 00:00:00 Jake        2               0           2

但是,使用此查询时,必须确保:

  • 违例令牌在令牌词之间的长度和间隔是独特且一致的,例如,添加新数据(如“ Reinf”)将产生不希望的输出,因为“ Reinf”是“ Reinf cecement”的一部分字符串,CHARINDEX()将产生大于0的输出。
  • 违规数据列值将仅包含不同的违规令牌的组合,因此'Early Parker;晚派克;帕克晚”将仅计入一个“帕克后期”,而不是两个。
  • 您已被警告..;)

因此,您可以从...快乐编码中选择几个答案。