【问题标题】:MYSQL self-join to select last year salesMYSQL自加入选择去年销量
【发布时间】:2011-11-12 04:30:48
【问题描述】:

我正在尝试从给定日期范围(t1.DATE >= '2011-01-01' AND t1.DATE

SELECT 
t1.date as DATE, SUM(t1.total), t2.date, sum(t2.total)
FROM T_SALES t1

LEFT OUTER JOIN T_SALES t2
on (t2.date = (t1.date - 1)
AND t2.rc = t1.rc
AND t2.storenum = t1.storenum)
WHERE 
    t1.RC = 0 
AND t1.STORENUM = '1,'
AND t1.DATE >= '2011-01-01' 
AND t1.DATE <= '2011-11-11' 
GROUP BY t1.date

ORDER BY t1.DATE ASC

我的第二个汇总 t2.total 是我的问题所在 - SUM(t1.total) 代表准确的销售总额)

下面是我的输出

值 27.90,应该是 5.58——看起来我在 sum(t2.total) 上求和了。

按 t1.total 分组也表明:(5.58 * 5 = 27.90)

我已经尝试了所有可以想象的分组,但就是无法做到正确,有什么想法吗?谢谢大家!

【问题讨论】:

  • 您想根据日期范围获取历史总数?我不明白你为什么要加入表格来做到这一点?我认为您需要提供有关您要实现的目标的更多详细信息,或者我的直觉是您试图在一个查询中做太多事情。我不明白为什么你想用 t1.Date = t2.Date - 1 将表加入到自身中。什么是 rc 字段?可能您想使用嵌套的选择查询,然后在日期将它们连接在一起。
  • 很明显(对我来说)OP 正在尝试比较日常销售额,这是零售业非常常见的指标。
  • 我认为 gregory 提出了一个很好的观点。单独加入一个表有点令人困惑,但是如果你想比较日期,你仍然可以通过使用子查询在 where 子句上执行此操作,这样你就再也不需要使用 join 语句了。
  • 自连接在 SQL 应用程序中很常见。

标签: mysql self-join


【解决方案1】:

您的问题是您在两个表之间得到一个半笛卡尔积 - T1 表中的两个销售和 T2 表中的三个销售将在预聚合结果集中产生六行。

有两种方法可以解决这个问题:

  1. 先聚合表,然后将聚合表连接在一起。

  2. 整个查询基于对第一个表的简单选择,并在结果中嵌套一个查询以获得第二个总数。

这是解决方案 1(请注意,这由 RC(区域代码?)和 storenum 分解,如果这不是您想要的,则简单地删除对这些列的所有引用):

CREATE VIEW DailyTotals (RC, StoreNum, Date, TotalAmount) AS 
SELECT RC, StoreNum, Date, SUM(Total) FROM T_Sales
GROUP BY RC, StoreNum, Date

SELECT TODAY.RC, TODAY.StoreNum, TODAY.Date, TODAY.TotalAmount, 
       YDAY.Date, YDAY.TotalAmount
FROM DailyTotals TODAY 
   LEFT OUTER JOIN DailyTotals YDAY ON YDAY.Date = TODAY.Date-1
WHERE TODAY.Date BETWEEN '2011-01-01' AND '2011-11-11'

这里是解决方案 2(同样是区域和商店细分,可以删除):

  SELECT RC, StoreNum, Date, SUM(Total), Date-1,
    (SELECT SUM(Total) FROM T_Sales YDAY WHERE 
     YDAY.RC = TODAY.RC AND YDAY.StoreNum = TODAY.StoreNum AND YDAY.Date = TODAY.Date-1)
  FROM T_Sales TODAY WHERE Date BETWEEN '2011-01-01' AND '2011-11-11'

【讨论】:

    【解决方案2】:

    也许是子选择?

    select *
      from (
    select sum(total)
         , date 
         , rc
         , storenum
     from T_SALES
    group by date, rc, storenum)T1
    left join(
    select sum(total)
         , date 
         , rc
         , storenum
     from T_SALES
    group by date, rc, storenum)T2
     on T2.date = (T1.date - 1)
    and T2.storenum = T1.storenum
    

    【讨论】:

      【解决方案3】:

      尝试将您的查询修改为如下内容:

      SELECT 
      t1.date as DATE, SUM(t1.total), t1.date, sum(t1.total)
      FROM T_SALES t1
      WHERE 
          t1.RC = 0 
      AND t1.STORENUM = '1,'
      t1.date BETWEEN '2011-01-01' AND '2011-11-11' 
      GROUP BY t1.date
      ORDER BY t1.date ASC
      

      您的别名 t1 和 t2 只是使用同一个表并再次执行您需要的计算。您之前的查询非常混乱。然后在 where 语句中添加您需要的条件,并在此处再次发布您的操作方式

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-09-18
        • 1970-01-01
        • 2012-06-16
        • 2012-08-26
        • 2016-04-05
        • 1970-01-01
        • 2015-09-28
        相关资源
        最近更新 更多