Sql 如何计算同一表的不同行组之间的差异

Sql 如何计算同一表的不同行组之间的差异,sql,Sql,有一张桌子,如: Year Month Value 2011 1 500 2011 2 550 2011 3 600 ... ... 2012 1 600 2012 2 750 2012 3 930 是否有一种方法可以计算同一个月/不同年份的值之间的差异,从而得出以下结果: Month Value 1 100 2 200 3 330 ...

有一张桌子,如:

Year   Month   Value
2011   1       500
2011   2       550
2011   3       600
...
...
2012   1       600
2012   2       750
2012   3       930
是否有一种方法可以计算同一个月/不同年份的值之间的差异,从而得出以下结果:

Month    Value
1        100
2        200
3        330
...
我试着做一些类似的事情:

select month, a.value-b.value
from
  (select month, value from table where year = 2012) a,
  (select month, value from table where year = 2011) b
但产量为2012年选择a的12个月*2011年选择b的12个月

编辑:很抱歉缺少重要信息:

通过odbc:jdbc桥对excel表进行查询


由于from子句总是这样:[sheet1$]我无法创建任何联接或事例:

您非常接近如何获得结果。我建议使用类似的方法,将数据旋转到列中,然后您可以计算每年的差异:

select month,
  Year2012-Year2011 as Diff
from
(
  select month,
    sum(case when year = 2011 then value end) Year2011,
    sum(case when year = 2012 then value end) Year2012
  from yourtable
  group by month
) src     

请参见

您非常接近如何获得结果。我建议使用类似的方法,将数据旋转到列中,然后您可以计算每年的差异:

select month,
  Year2012-Year2011 as Diff
from
(
  select month,
    sum(case when year = 2011 then value end) Year2011,
    sum(case when year = 2012 then value end) Year2012
  from yourtable
  group by month
) src     

请参见

您想进行自联接。一般的想法是从同一个表中选择两次,但别名不同

select t1.something, t2.something
from yourtable t1 join yourtable t2 on something
etc

您想进行自联接。一般的想法是从同一个表中选择两次,但别名不同

select t1.something, t2.something
from yourtable t1 join yourtable t2 on something
etc

查询不起作用,因为您正在表上执行交叉联接,因此每一行都与另一个表中的每一行匹配,而不是当月的内部联接

修改您的查询:

更快的查询:

对于每年每月多行:

select month,
  Year2012-Year2011 as Diff
from
(
  select month,
    sum(case when year = 2011 then value end) Year2011,
    sum(case when year = 2012 then value end) Year2012
  from yourtable
  group by month
) src     

.

您的查询不起作用,因为您在表上执行交叉联接,因此每一行都与另一个表中的每一行匹配,而不是当月的内部联接

修改您的查询:

更快的查询:

对于每年每月多行:

select month,
  Year2012-Year2011 as Diff
from
(
  select month,
    sum(case when year = 2011 then value end) Year2011,
    sum(case when year = 2012 then value end) Year2012
  from yourtable
  group by month
) src     

.

像这样的吗?假设年/月是唯一的

SELECT
    a.month,
    a.value - b.value
FROM
    tablename a
    INNER JOIN tablename b
        ON a.year - 1 = b.year
        AND a.month = b.month

像这样的?假设年/月是唯一的

SELECT
    a.month,
    a.value - b.value
FROM
    tablename a
    INNER JOIN tablename b
        ON a.year - 1 = b.year
        AND a.month = b.month

选择a.month,a.value-从@tablename b中选择b.value,其中b.year=@year2和b.month=a.month作为差异 来自@tablename a 其中a.year=@year1


我想这会对你有帮助。事实上,我们知道,我们只能用两个数字进行减法,所以这里我用了第一年和第二年。将表名放在适当的位置

选择a.month,a.value-从@tablename b中选择b.value,其中b.year=@year2和b.month=a.month作为差异 来自@tablename a 其中a.year=@year1

我想这会对你有帮助。事实上,我们知道,我们只能用两个数字进行减法,所以这里我用了第一年和第二年。将表名放在适当的位置

只需将where子句添加到查询中即可

select month, a.value-b.value
from
  (select month, value from table where year = 2012) a,
  (select month, value from table where year = 2011) b
where a.month = b.month
您所做的是交叉连接,将第一个表中的每一行与第二列中的每一行进行组合,其中将筛选出与不同月份号匹配的行。

只需将where子句添加到查询中即可

select month, a.value-b.value
from
  (select month, value from table where year = 2012) a,
  (select month, value from table where year = 2011) b
where a.month = b.month

你所做的是交叉连接,将第一个表中的每一行与第二列中的每一行进行组合,其中将筛选出与不同月号匹配的行。

此外,如果您的示例中每个月只有2个值,并且您的SQL版本中提供了分析函数,则这将起作用。您可以用不同的方式对其进行分区…:

SELECT distinct month, (l_val - f_val) value
  FROM
  (
  SELECT year, month, month_val
       , FIRST_VALUE(month_val) OVER (PARTITION BY month ORDER BY month) f_val 
      , LAST_VALUE(month_val) OVER (PARTITION BY month ORDER BY month) l_val 
    FROM your_table
  )
 ORDER BY 1
 /

MONTH    VALUE
----------------
1        100
2        200
3        330

在我个人看来,内联视图最好使用then join,尽管您无论如何都会加入,但它更可读,更易于调试……

此外,如果您的示例中每个月只有2个值,并且您的SQL版本中提供了分析函数,那么这将起作用。您可以用不同的方式对其进行分区…:

SELECT distinct month, (l_val - f_val) value
  FROM
  (
  SELECT year, month, month_val
       , FIRST_VALUE(month_val) OVER (PARTITION BY month ORDER BY month) f_val 
      , LAST_VALUE(month_val) OVER (PARTITION BY month ORDER BY month) l_val 
    FROM your_table
  )
 ORDER BY 1
 /

MONTH    VALUE
----------------
1        100
2        200
3        330

在我个人看来,内联视图最好使用然后加入,尽管你无论如何都会加入,但它更可读,更易于调试…

你想要的输出是什么?你想要的输出是什么?当他有2013年、2014年等年时会发生什么。我们可以使用通用查询吗?@AshReva您可以创建一个动态查询来生成年份列表,但OP必须说明他们使用的RDBMS,因为每个RDBMS的语法都不同。@AshReva执行此查询的方法有很多种。当他有2013年、2014年等年份时会发生什么。我们可以使用通用查询吗?@AshReva您可以创建一个动态查询来生成年份列表,但OP必须说明他们使用的RDBMS,因为每个RDBMS的语法都不同。@AshReva执行此查询的方法有很多种。