Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 不存在的组项目类别计数为零_Sql_Sql Server_Tsql_Group By - Fatal编程技术网

Sql 不存在的组项目类别计数为零

Sql 不存在的组项目类别计数为零,sql,sql-server,tsql,group-by,Sql,Sql Server,Tsql,Group By,我需要找到过去五天内三种产品的清单,以及按日期分组的数量。为此,我使用了下面的TSQL SELECT CONVERT(VARCHAR(10),WM_data,103) as Date, Product = CASE WHEN WM_Product = 1 THEN 'Product A' WHEN WM_Product = 2 THEN 'Product B'

我需要找到过去五天内三种产品的清单,以及按日期分组的数量。为此,我使用了下面的TSQL

SELECT CONVERT(VARCHAR(10),WM_data,103) as Date, 
       Product = CASE 
                   WHEN WM_Product = 1 THEN 'Product A' 
                   WHEN WM_Product = 2 THEN 'Product B' 
                   ELSE 'Product C' 
                 END, 
       WM_qtd as Quantity 
  FROM Tb_InfoProduct 
GROUP BY CONVERT(VARCHAR(10),WM_data,103), WM_Product
  HAVING CONVERT(VARCHAR(10),WM_data,103) > convert(VARCHAR(10),dateadd(dd, -5, getdate()),103) 
ORDER BY CONVERT(VARCHAR(10),WM_data,103), WM_Product
因此,我收到:

Date          Product     Quantity
-------------------------------------------------
16/02/2012    Product A    132
16/02/2012    Product C     10
17/02/2012    Product A    163
17/02/2012    Product B     61
17/02/2012    Product C     58
18/02/2012    Product A      7
18/02/2012    Product B      2
但我需要:

Date     Product     Quantity
-------------------------------------------------
16/02/2012   Product A   132
16/02/2012   Product B     0  -- This
16/02/2012   Product C    10
17/02/2012   Product A   163
17/02/2012   Product B    61
17/02/2012   Product C    58
18/02/2012   Product A     7
18/02/2012   Product B     2
18/02/2012   Product C     0   -- This

如何实现这一点?

首先,您的查询存在一些问题:

  • 您的
    SELECT
    子句包含的列既不在
    groupby
    中,也不在聚合的–
    WM\u qtd
    中。你的意思是求和,不是吗

  • 通常,使用
    CONVERT(103)
    格式化的日期无法进行有意义的比较或排序。我建议您要么使用不同的格式(如
    112
    ),要么使用不同的方法删除时间部分,然后再应用格式(仅在
    SELECT
    子句中,或者根本不在SQL中)

  • 您使用
    HAVING
    子句过滤源数据集,这是低效的,因为所有数据都必须被提取、分组,然后才进行过滤。在这种特殊情况下,最好使用
    WHERE
    子句过滤数据

  • 至于你的问题。。。你所追求的结果集基本上是所有相关日期和所有相关产品的叉积(哦,对不起,这个双关语)。它只包含一些附加信息,比如数量

    因此,您需要获取两个列表,日期和产品,交叉连接它们,然后可以将结果集外部连接到
    Tb\u InfoProduct
    ,并按日期和产品分组以获取数字–与您在查询中已经做的相同,只有您的
    分组依据
    选择
    子句将引用的日期和产品列必须是相应派生列表中的列,而不是
    Tb\u InfoProduct
    表中的列

    出于回答的目的,我假设您请求的
    Tb\u InfoProduct
    子集包含输出中必须存在的所有日期和所有产品,因此,要获得这两个列表,我只需从
    Tb\u InfoProduct
    子集中选择不同的日期和不同的产品。这是一个完整的近似解决方案:

    SELECT
      Date = CONVERT(VARCHAR(10), d.Date, 103),
      Product = CASE p.WM_Product
        WHEN 1 THEN 'Product A'
        WHEN 2 THEN 'Product B'
        ELSE        'Product C'
      END,
      Quantity = SUM(WM_qtd)
    FROM (
      SELECT DISTINCT Date = DATEADD(DAY, DATEDIFF(DAY, 0, WM_data), 0)
      FROM Tb_InfoProduct
      WHERE WM_data >= DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()) - 4, 0)
    ) d
    CROSS JOIN (
      SELECT DISTINCT WM_Product
      FROM Tb_InfoProduct
      WHERE WM_data >= DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()) - 4, 0)
    ) p
    LEFT JOIN (
      SELECT
        Date = DATEADD(DAY, DATEDIFF(DAY, 0, WM_data), 0),
        WM_Product
      FROM Tb_InfoProduct
      WHERE WM_data >= DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()) - 4, 0)
    ) i ON d.Date = i.Date AND p.WM_Product = i.WM_Product
    GROUP BY
      d.Date,
      p.WM_Product
    ORDER BY
      d.Date,
      p.WM_Product
    
    如果请求的子集可能会忽略您希望包含在输出中的某些日期和/或产品,则应以不同的方式构建列表。例如,您可以使用
    Products
    引用表作为产品列表,当然,如果您有一个产品列表的话。至于日期,您可能需要按照@OMG Ponies的建议为给定范围生成日期列表(这个问题可能会帮助您:)。

    如果使用sql 2008:

    SELECT table1.date, table2.productid, isnull(table3.total,0) total FROM
    --get the last 5 days
    (
    select distinct date from mytable1 where date > getdate() - 5
    ) table1
    --get the 3 products
    CROSS JOIN
    (
    select productid from product where productid in (1,2,3)
    ) table2
    OUTER APPLY (SELECT SUM(1) Total from YourTable 
        where yourtable.date = table1.date 
        and yourtable.productid = table2.productid) Table3
    

    您需要有(或生成)一个日期列表,然后在日期值上与之外部连接。另外,您应该在
    WHERE
    子句中进行筛选(使用日期对象而不是字符串)