自2016年12月12日至15/05/17,每天使用了多少封信件

时间:2017-05-15 14:40:48

标签: sql sql-server tsql sql-server-2012

我想创建一个报告,我计算每个字母每天用水晶字母作为个性化的次数。

  SELECT 

   [Order]
  ,[Style]
  ,[Text]  

  FROM [Item Personalisation] as 
  OP
   INNER JOIN  [Order Header] AS 
  OH 
  ON OH.[Order Guid]=OP.[Owner Header GuID]
  WHERE [Personalisation] ='CRYSTALS'
  AND [Order Date]>= '2016-12-07T00:00:00.000' AND 
  [Order Date] <= '2016-12-07T00:00:00.000' 

如果我在查询之上运行,则会得到以下结果集。

 Order       Style      Text
 23099557   CRYSTALS    CM
 23104712   CRYSTALS    HJC
 23107055   CRYSTALS    IMO
 23107904   CRYSTALS    JH
 23108782   CRYSTALS    GAB
 22320464   CRYSTALS    ZLR

所以我只运行了一天,但我需要在白天至2017年5月15日之前获得结果,并想知道每个字母的使用日期是多少次,结果集如下表所示。

              07/12/2016    08/12/2016  09/12/2016  10/12/2016 -- 15/05/2017
 Letter A               
 Letter B               
 Letter C
 - to  - 
 Letter Z               

请帮忙。

3 个答案:

答案 0 :(得分:0)

只是为了好玩。这是一个动态的数据透视表(许多示例),其中源是按日期不透明,通过交叉应用来使用ad-hoc计数表。

为了保持正方形,我们扔了一个联盟,以确保列出所有26个字母。

示例

Declare @Date1 date = '2016-12-07'
Declare @Date2 date = '2017-05-15'

Declare @SQL varchar(max) = Stuff((Select Distinct ',' + QuoteName(OrderDate) 
                                    From  Yourtable 
                                    Where OrderDate between @Date1 and @Date2 
                                    Order by 1 
                                    For XML Path('')
                                  ),1,1,'') 
Select  @SQL = '
Select *
From (
        Select A.OrderDate
              ,B.*
         From  YourTable A
         Cross Apply (
                        Select Top (len(A.Text)) substring(A.Text,Row_Number() Over (Order By Number),1),1 
                         From  master..spt_values 
                     ) B (Letter,Cnt)
         Where OrderDate between '''+convert(varchar(10),@Date1,112)+''' and '''+convert(varchar(10),@Date2,112)+'''
           and Letter like ''[a-zA-Z]''
        Union All
        Select Top (26) '''+convert(varchar(10),@Date1,112)+''',char(Row_Number() Over (Order By Number)+64),null  From master..spt_values 
     ) A
Pivot (count(Cnt) For [OrderDate] in (' + @SQL + ') ) p
Order By Letter
'

Exec(@SQL);

<强>返回

enter image description here

如果有帮助,则会生成以下SQL。

Select *
From (
        Select A.OrderDate
              ,B.*
         From  YourTable A
         Cross Apply (
                        Select Top (len(A.Text)) substring(A.Text,Row_Number() Over (Order By Number),1),1 
                         From  master..spt_values 
                     ) B (Letter,Cnt)
         Where OrderDate between '20161207' and '20170515'
           and Letter like '[a-zA-Z]'
        Union All
        Select Top (26) '20161207',char(Row_Number() Over (Order By Number)+64),null  From master..spt_values 
     ) A
Pivot (count(Cnt) For [OrderDate] in ([2016-12-07],[2016-12-08],[2016-12-09],[2016-12-10]) ) p
Order By Letter
  

编辑 - 更新了实际表格和字段名称

静态版本应该是什么样子

Select * 
 From ( 
       Select oh.[Order Date] 
             ,b.*
        From  [TBW_BI].[dbo].[Internet Order Personalisation] A 
        INNER JOIN [TBW_BI].[dbo].[Feelunique Trading$Internet Order Header] AS OH ON OH.[Order Guid]=a.[Owner Header GuID] 
        Cross Apply (
                      Select Top (len(A.[Personalisation Text])) substring(A.[Personalisation Text],Row_Number() Over (Order By Number),1),1 
                       From  master..spt_values 
                     ) B (Letter,Cnt)
        Where [Order Date] between '20161207' and '20161209' 
          and Letter like '[a-zA-Z]%' 
          and [Personalisation Style] ='CRYSTALS' 
        Union All 
        Select Top (26) '20161207',char(Row_Number() Over (Order By Number)+64),null From master..spt_values 
     ) A 
Pivot (count(cnt) For [Order Date] in ([2016-12-07],[2016-12-08],[2016-12-09])) P 
Order By letter 
Exec(@SQL)

答案 1 :(得分:0)

NGrams8K是一个纯粹的T-SQL函数,专为 完全 此类任务而设计。

这会创建一个字母:

SELECT letter = token FROM dbo.NGrams8k('ABCDEFGHIJKLMNOPQRSTUVWXYZ',1);

以下是我们可以用来按天计算字符的一些示例数据和逻辑。

DECLARE @yourtable TABLE 
(
  txt varchar(8000),
  someDate date
);

INSERT @yourtable (txt, somedate)
VALUES 
('Video provides a powerful way to help you prove your point. When you click Online Video, you can paste in the embed code for the video you want to add. You can also type a keyword to search online for the video that best fits your document.', '20161207'),
('To make your document look professionally produced, Word provides header, footer, cover page, and text box designs that complement each other. For example, you can add a matching cover page, header, and sidebar. Click Insert and then choose the elements you want from the different galleries.', '20161208'),
('Themes and styles also help keep your document coordinated. When you click Design and choose a new Theme, the pictures, charts, and SmartArt graphics change to match your new theme. When you apply styles, your headings change to match the new theme.', '20161209'),
('Save time in Word with new buttons that show up where you need them. To change the way a picture fits in your document, click it and a button for layout options appears next to it. When you work on a table, click where you want to add a row or a column, and then click the plus sign.','20161210');
WITH 
yourtxt AS
(
  SELECT SomeDate, letter = token 
  FROM @yourtable
  CROSS APPLY dbo.NGrams8k(txt, 1)
),
alphabet AS
(
  SELECT letter = token
  FROM dbo.NGrams8k('ABCDEFGHIJKLMNOPQRSTUVWXYZ',1)
),
matrix AS
(
  SELECT t.someDate, a.letter, total = COUNT(t.letter) 
  FROM alphabet a
  LEFT JOIN yourtxt t ON a.letter = t.letter
  GROUP BY t.someDate, a.letter
)
SELECT * 
FROM matrix;

该代码将为您提供:

someDate   letter 
---------- -------
2016-12-07 A      
2016-12-08 A      
2016-12-09 A      
2016-12-10 A      
2016-12-07 B      
2016-12-08 B      
2016-12-10 B      
2016-12-07 C      
2016-12-08 C      
2016-12-09 C      
....
2016-12-08 X
2016-12-10 X
2016-12-07 Y
2016-12-08 Y
2016-12-09 Y
2016-12-10 Y

有几点需要注意:我在美国,所以我在逻辑(yyyymmdd)中使用标准日期格式,但是以您正在使用的格式输出日期。另请注意,在某些日子里,所有日期都没有使用过字母(例如x,z)。最后,为了简洁起见,我只是通过20161210做样本数据。

我们需要做的最后一件事是使用这个逻辑来转移数据:

WITH 
yourtxt AS
(
  SELECT SomeDate, letter = token 
  FROM @yourtable
  CROSS APPLY dbo.NGrams8k(txt, 1)
),
alphabet AS
(
  SELECT letter = token
  FROM dbo.NGrams8k('ABCDEFGHIJKLMNOPQRSTUVWXYZ',1)
),
matrix AS
(
  SELECT t.someDate, a.letter, total = COUNT(t.letter) 
  FROM alphabet a
  LEFT JOIN yourtxt t ON a.letter = t.letter
  GROUP BY t.someDate, a.letter
)
SELECT 
  matrix.letter,
  ISNULL(MAX(CASE matrix.someDate WHEN '20161207' THEN total END),0) AS [07/12/2016],
  ISNULL(MAX(CASE matrix.someDate WHEN '20161208' THEN total END),0) AS [08/12/2016],
  ISNULL(MAX(CASE matrix.someDate WHEN '20161209' THEN total END),0) AS [09/12/2016],
  ISNULL(MAX(CASE matrix.someDate WHEN '20161210' THEN total END),0) AS [10/12/2016]
FROM matrix
GROUP BY matrix.letter;

该代码返回:

letter  07/12/2016  08/12/2016  09/12/2016  10/12/2016
------- ----------- ----------- ----------- -----------
A       11          19          16          17
B       2           2           0           3
C       7           11          12          10
D       11          15          8           7
E       23          35          28          20
F       4           6           0           2
G       0           5           5           2
H       7           10          17          11
I       11          9           6           13
J       0           0           0           0
K       2           3           2           4
L       6           9           6           7
M       2           8           8           4
N       11          14          14          18
O       26          23          13          21
P       7           7           6           6
Q       0           0           0           0
R       9           17          9           10
S       6           10          13          8
T       15          17          18          25
U       9           5           7           12
V       6           3           0           1
W       5           2           5           11
X       0           3           0           1
Y       10          4           8           6
Z       0           0           0           0

您可以在本文中了解有关NGrams8K的更多信息:Nasty Fast N-Grams (Part 1): Character-Level NGrams

答案 2 :(得分:-2)

我不知道哪些表具有哪些值,并假设您的连接每次使用返回1条记录,我还假设日期是固定的。我个人更喜欢下面的案例陈述。我只做了两列,但它应该给你一个想法。

SELECT  [Text],
        SUM(CASE
                WHEN [Order Date] >= '20160712'
                     AND [Order Date] < '20160713'
                     THEN 1
                ELSE 0
            END
            ) AS [20160712],
        SUM(CASE
                WHEN [Order Date] >= '20160713'
                     AND [Order Date] < '20160714'
                     THEN 1
                ELSE 0
            END
            ) AS [20160713]
FROM    [Item Personalisation] AS [OP]
    INNER JOIN [Order Header] AS [OH]
        ON     [OH].[Order Guid] = [OP].[Owner Header GuID]
WHERE   [Personalisation] = 'CRYSTALS'
        AND [Order Date]  >= '20161207'
        AND [Order Date]  <= '20161215'
GROUP BY [Text];