使用Access在SQL中按年份进行数据比较

时间:2015-04-09 09:38:02

标签: sql ms-access parameters comparison pivot

我需要按年份对数据进行并排比较。

我正在使用Microsoft Access 2013。

我想要获得的是这样的表:

╔══════╦══════════╦ ... ╦═══════╦═══════════════╦══════════════╦════════════╗
║ Zone ║ Customer ║ ... ║ Month ║ Previous year ║ Current year ║ Difference ║
╠══════╬══════════╬ ... ╬═══════╬═══════════════╬══════════════╬════════════╣
║ PD   ║ A        ║ ... ║     1 ║ 100€          ║ 150€         ║ +50€       ║
║ PD   ║ B        ║ ... ║     2 ║ 150€          ║ 100€         ║ -50€       ║
║ PD   ║ C        ║ ... ║     1 ║ 200€          ║ 0€           ║ -200€      ║
║ PD   ║ D        ║ ... ║     2 ║ 0€            ║ 100€         ║ +100€      ║
╚══════╩══════════╩ ... ╩═══════╩═══════════════╩══════════════╩════════════╝

("..." stands for other columns)

确定前一年是2014年,当前是2015年,通过此表我可以看到:

  • 2014年客户已在2015年(客户A)购买更多;
  • 2014年客户已在2015年(客户B)购买更少;
  • 2015年客户尚未购买(客户C);
  • 2015年有新客户(客户D)。

当我有一个2015年没有购买的“旧”(2014)客户时我需要在“当前年度”栏目(2015年)中看到“0€”值的那一行等等同样对于2015年的新客户来说,显然在2014年没有购买任何东西。

这些是我的表格:

  • CUSTOMERS(id,company_name,id_zone,id_customer_category)
  • CUSTOMER_CATEGORIES(id,description)
  • ORDERS(id,id_customer,date,qty,amount(€),id_product_category, id_import)
  • PRODUCT_CATEGORIES(id,supplier,description)
  • ZONES(id,city)
  • 进口(id,年,月,供应商)

我创建了一个视图( V_YEAR_SALES ):

SELECT Z.ID AS ID_ZONE, Z.CITY, C.COMPANY_NAME AS CUSTOMER, CAT.DESCRIPTION AS CUSTOMER_CATEGORY, P.SUPPLIER, P.DESCRIPTION AS PRODUCT_CATEGORY, I.MONTH, I.YEAR, SUM(O.AMOUNT) AS AMOUNT
FROM ((((ORDERS AS O 
    INNER JOIN CUSTOMERS AS C ON O.ID_CUSTOMER = C.ID) 
    INNER JOIN ZONES AS Z ON Z.ID = C.ID_ZONE) 
    INNER JOIN IMPORTS AS I ON I.ID = O.ID_IMPORT) 
    INNER JOIN CUSTOMER_CATEGORIES AS CAT ON CAT.ID = C.ID_CUSTOMER_CATEGORY)
    INNER JOIN PRODUCT_CATEGORIES AS P ON O.ID_PRODUCT_CATEGORY = P.ID
GROUP BY Z.ID, Z.CITY, C.COMPANY_NAME, CAT.DESCRIPTION, P.SUPPLIER, P.DESCRIPTION, I.MONTH, I.YEAR
ORDER BY Z.CITY, P.SUPPLIER, P.DESCRIPTION, CAT.DESCRIPTION, C.COMPANY_NAME, I.YEAR, I.MONTH;

每次我需要在一年和上一年之间进行比较时,我会使用此视图( V_SALES_COMPARISON )来传递年份:

SELECT S1.ID_ZONE, S1.CITY, S1.ID_CUSTOMER, S1.CUSTOMER, S1.ID_CUSTOMER_CATEGORY, S1.CUSTOMER_CATEGORY, S1.SUPPLIER, S1.ID_PRODUCT_CATEGORY, S1.PRODUCT_CATEGORY, S1.YEAR, S1.MONTH, S1.AMOUNT AS CURRENT_YEAR, S2.AMOUNT AS PREVIOUS_YEAR, S1.AMOUNT - S2.AMOUNT AS DIFFERENCE
FROM 
    (SELECT * FROM V_YEAR_SALES) AS S1 
    LEFT JOIN 
    (SELECT * FROM V_YEAR_SALES) AS S2 
        ON (S1.ID_ZONE = S2.ID_ZONE) 
        AND (S1.SUPPLIER = S2.SUPPLIER) 
        AND (S1.ID_PRODUCT_CATEGORY = S2.ID_PRODUCT_CATEGORY) 
        AND (S1.ID_CUSTOMER_CATEGORY = S2.ID_CUSTOMER_CATEGORY) 
        AND (S1.ID_CUSTOMER = S2.ID_CUSTOMER) 
        AND (S1.YEAR = S2.YEAR + 1) 
        AND (S1.MONTH = S2.MONTH);

参考上述所需结果表,使用此视图,我只能获得客户A,B,D 但不是C 的行!

我需要包括2014年尚未购买的客户!

我正在使用JOIN,但我不知道这是否是最佳方法。也许我可以使用PIVOTING,但我不知道是否以及如何使用Access实现。

2 个答案:

答案 0 :(得分:0)

你可以这样:

SELECT 
    Customer, 
    Sum(IIf(DateDiff("yyyy",[InvoiceDate],Date())=1,[Amount],0)) AS LastYear, 
    Sum(IIf(DateDiff("yyyy",[InvoiceDate],Date())=0,[Amount],0)) AS ThisYear, 
    Sum(IIf(DateDiff("yyyy",[InvoiceDate],Date())=0,[Amount],0)) 
       - Sum(IIf(DateDiff("yyyy",[InvoiceDate],Date())=1,[Amount],0)) AS Diff
FROM 
    Invoices
GROUP BY 
    Customer;

我看到你有一个单独的年份字段,所以试试这个方法:

SELECT 
    Customer, 
    Sum(IIf(Year(Date())-[YearField]=1,[Amount],0)) AS LastYear, 
    Sum(IIf(Year(Date())-[YearField]=0,[Amount],0)) AS ThisYear, 
    Sum(IIf(Year(Date())-[YearField]=0,[Amount],0)) 
       - Sum(IIf(Year(Date())-[YearField]=1,[Amount],0)) AS Diff
FROM 
    Invoices
GROUP BY 
    Customer;

答案 1 :(得分:0)

最后,我使用 PIVOTING 找到了解决方案。

V_YEAR_SALES 视图已替换为:

TRANSFORM
IIF(SUM(O.AMOUNT) IS NULL, 0, SUM(O.AMOUNT))
SELECT Z.ID AS ID_ZONE, Z.CITY, C.COMPANY_NAME AS CUSTOMER, CAT.DESCRIPTION AS CUSTOMER_CATEGORY, P.SUPPLIER, P.DESCRIPTION AS PRODUCT_CATEGORY, I.MONTH, I.YEAR
FROM ((((ORDERS AS O 
    INNER JOIN CUSTOMERS AS C ON O.ID_CUSTOMER = C.ID) 
    INNER JOIN ZONES AS Z ON Z.ID = C.ID_ZONE) 
    INNER JOIN IMPORTS AS I ON I.ID = O.ID_IMPORT) 
    INNER JOIN CUSTOMER_CATEGORIES AS CAT ON CAT.ID = C.ID_CUSTOMER_CATEGORY)
    INNER JOIN PRODUCT_CATEGORIES AS P ON O.ID_PRODUCT_CATEGORY = P.ID
WHERE I.YEAR BETWEEN 
    (SELECT MAX(YEAR) FROM IMPORTS) AND (SELECT MAX(YEAR)-3 FROM IMPORTS)
GROUP BY Z.ID, Z.CITY, C.COMPANY_NAME, CAT.DESCRIPTION, P.SUPPLIER, P.DESCRIPTION, I.MONTH, I.YEAR

V_SALES_COMPARISON视图已删除,因为不再需要了。我的查询现在仅适用于V_YEAR_SALES

查询新V_YEAR_SALES 更快 <{1}}。

如果您需要从Access或不带参数查询视图:

V_SALES_COMPARISON

相反,如果您需要使用Jet Driver从代码查询视图,并且您还想使用参数,则需要执行以下操作:

SELECT S.*
FROM V_YEAR_SALES AS S
WHERE S.YEAR IN (2015, 2014) AND S.MONTH BETWEEN 1 AND 12;

要小心要包含PARAMETERS P0 TEXT(255), P1 TEXT(255), P2 TEXT(255), P3 TEXT(255); SELECT S.* FROM V_YEAR_SALES AS S WHERE S.YEAR IN (@P0, @P1) AND S.MONTH BETWEEN @P2 AND @P3; 声明(PARAMETERS声明之前还有;),否则你会从Jet Driver收到错误:

SELECT