我有下表Sales:
Date Store Sales
1/1/2015 St01 12123
1/1/2015 St02 3123
1/1/2016 St01 4213
1/1/2016 St03 2134
当我尝试自己加入今年和去年的销售时,封闭的商店没有出现。 结果应该是这样的:
Date Store This year Sales Last Year Sales
1/1/2016 St01 4213 1212
1/1/2016 St02 0 3123
1/1/2016 St03 2134 0
我的查询如下:
SELECT CY.DATE,
CY.store cy.Sales,
LY.sales
FROM sales CY,
sales LY
WHERE CY.store(+) = LY.store(+)
AND LY.DATE = CY.DATE - 365
答案 0 :(得分:0)
您需要什么称为透视表。虽然Oracle有特定的条款来执行此操作,但您可以使用纯SQL和纯SQL来执行此操作,如下所示:
SELECT store,
SUM(CASE WHEN Extract(year FROM DATE) = Extract(year FROM SYSDATE) THEN
sales
ELSE 0
END) AS "This year Sales",
SUM(CASE WHEN Extract(year FROM DATE) = Extract(year FROM SYSDATE) - 1 THEN
sales
ELSE 0
END) AS "Last year Sales"
FROM sales
WHERE Extract(year FROM DATE) >= Extract(year FROM SYSDATE) - 1
GROUP BY store
ORDER BY store
它会显示:
Store This year Sales Last year Sales
St01 4213 12123
St02 0 3123
St03 2134 0
请注意,将列date
作为第一列是没有意义的。你不能按它分组以显示你想要的输出。
在此处查看此查询的等效内容:http://sqlfiddle.com/#!15/7662d8/6
答案 1 :(得分:0)
Oracle安装程序:
CREATE TABLE sales ( "DATE", Store, Sales ) AS
SELECT DATE '2015-01-01', 'St01', 12123 FROM DUAL UNION ALL
SELECT DATE '2015-01-01', 'St02', 3123 FROM DUAL UNION ALL
SELECT DATE '2016-01-01', 'St01', 4213 FROM DUAL UNION ALL
SELECT DATE '2016-01-01', 'St03', 2134 FROM DUAL;
<强>查询强>:
SELECT TRUNC( SYSDATE, 'YY' ) AS "DATE",
Store,
SUM( CASE WHEN "DATE" = TRUNC( SYSDATE, 'YY' )
THEN sales END )
AS "This year sales",
SUM( CASE WHEN "DATE" = ADD_MONTHS( TRUNC( SYSDATE, 'YY' ), -12 )
THEN sales END )
AS "Last year sales"
FROM sales
GROUP BY store
ORDER BY store;
<强>输出强>:
DATE STORE This year sales Last year sales
------------------- ----- --------------- ---------------
2016-01-01 00:00:00 St01 4213 12123
2016-01-01 00:00:00 St02 3123
2016-01-01 00:00:00 St03 2134
答案 2 :(得分:0)
由于我希望查询逐日返回销售,我使用了MT0回答并添加了日期,这样我就可以获得所有年份的数据。
WITH AllYear AS
(select to_date('2016-01-01', 'yyyy-mm-dd') + level - 1 AS dobs
from dual
connect by level <= 366)
SELECT dobs AS "DATE",
Store,
nvl(SUM(CASE
WHEN t.Date = dobs THEN
t.sales
END),
0) AS "This Year Sales",
nvl(SUM(CASE
WHEN t.Date = dobs-365 THEN
t.sales
END),
0) AS "Last Year Sales"
FROM Sales t,AllYear
where dobs='01-Jan-2016'
GROUP BY Store
ORDER BY Store;
答案 3 :(得分:-1)
一般解决方案是完整外部联接,其中包括来自两个联接表的所有记录。我不知道Oracle语法,但在MS SQL Server中它将是这样的:
SELECT ISNULL(CY.DATE, LY.DATE) as DATE,
ISNULL(CY.store, LY.store) as STORE,
isnull(cy.Sales, 0),
isnull(LY.sales, 0)
FROM sales CY FULL OUTER JOIN sales LY
ON CY.store = LY.store
AND (CY.DATE IS NULL OR
DATEPART(year, LY.DATE) = DATEPART(year, CY.DATE) - 1
ISNULL(a, b)
如果a
,则为A IS NOT NULL
,否则为b
。 DATEPART
提取日期的指定部分;我正在比较一年而不是365天的差异,以防“去年”是闰年/
答案 4 :(得分:-2)
我只使用SQL Server。如果有什么不同,请尝试应用相同的逻辑。
声明临时表以测试查询:
DECLARE @Sales TABLE (
[Date] DATE,
Store NVARCHAR(10),
Sales INT
)
INSERT INTO @Sales VALUES
('1/1/2015','St01',12123),
('1/1/2015','St02',3123),
('1/1/2016','St01',4213),
('1/1/2016','St03',2134);
SELECT * FROM @Sales;
实际查询:
SELECT
CY_Date = CASE
WHEN CY.Date IS NULL THEN DATEADD(YEAR, 1, LY.Date)
ELSE CY.Date
END,
LY_Date = CASE
WHEN LY.Date IS NULL THEN DATEADD(YEAR, -1, CY.Date)
ELSE LY.Date
END,
Store = CASE
WHEN CY.Store IS NULL THEN LY.Store
ELSE CY.Store
END,
ISNULL(CY.Sales, 0) AS CY_Sales,
ISNULL(LY.Sales, 0) AS LY_Sales
FROM @Sales CY
FULL JOIN @Sales LY ON (CY.Store = LY.Store AND LY.Date = DATEADD(YEAR, -1, CY.Date))
WHERE (CY.Date = '1/1/2016' OR CY.Date IS NULL)
AND (LY.Date = DATEADD(YEAR, -1, '1/1/2016') OR LY.Date IS NULL);
<强>结果:强>
CY_Date LY_Date Store CY_Sales LY_Sales
2016-01-01 2015-01-01 St01 4213 12123
2016-01-01 2015-01-01 St03 2134 0
2016-01-01 2015-01-01 St02 0 3123
工作原理: