2016-03-07 20 views
0

我一直在处理这些查询,然后进行了一些处理,但是我似乎无法弄清楚这三个问题。我真的不想让人们为我做我的工作,但任何帮助/提示将非常感激。SQL中的函数,日期,CASE和IIF语句存在严重问题

该查询应该返回4列:VENDORNAME,InvoiceTotal, InvoiceDate和InvoiceAge(使用相应的功能,这将 返回与invoiceDate和2008年12月1日之间的天数)。 筛选结果以仅返回有余额为 且InvoiceAge大于132的行。按 VendorName排序结果。没有错误,但并不完全正确。

SELECT VendorName, InvoiceTotal, InvoiceDate, 
DATEDIFF(day, InvoiceDate, '12/1/2008') AS InvoiceAge 
FROM Vendors JOIN Invoices 
ON Vendors.VendorID = Invoices.VendorID 
WHERE InvoiceTotal - PaymentTotal - CreditTotal > 0 
AND InvoiceDate > 132 
ORDER BY VendorName;-- Not showing invoices over 132 

这个查询是一直给我最麻烦的;它应该返回4列:VendorName,InvoiceNumber, InvoiceTotal和PotentialDiscount。 PotentialDiscount是将包含从包含基于InvoiceTotal列4个条件语句一个 CASE语句的结果表达式中的列:

SELECT VendorName, InvoiceNumber, InvoiceTotal, PotentialDiscount = 
CASE InvoiceTotal 
WHEN InvoiceTotal < 100 THEN 'No discount consideration' 
WHEN InvoiceTotal 101-500 THEN 'Discount potential 3' 
WHEN InvoiceTotal > 501-1000 THEN 'Discount potential 2' 
WHEN InvoiceTotal > 1000 THEN 'Discount potential 1' 
END AS PotentialDiscount 
FROM Vendors JOIN Invoices 
ON Vendors.VendorID = Invoices.VendorID 
ORDER BY InvoiceTotal; 

不过,我得到这个错误:

Msg 102, Level 15, State 1, Line 3 Incorrect syntax near '<'.

最后,这一个应该返回3列:VendorName,BalanceDue:使用SUM函数计算出的应付余额,DebtLevel:嵌套的IIF函数,然后过滤结果以仅包括供应商存在余额的情况,并将结果从最大余额最小。

SELECT VendorName, SUM(InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue, 
IIF(SUM(InvoiceTotal) > 11000, 'Very high', 
IIF(SUM(InvoiceTotal) BETWEEN 11000 AND 500, 'High', 
IIF(SUM(InvoiceTotal) BETWEEN 500 AND 200, 'Medium', 
IIF(SUM(InvoiceTotal) <= 500, 'Low') AS DebtLevel 
FROM Vendors JOIN Invoices 
ON Vendors.VendorID = Invoices.InvoiceID 
WHERE InvoiceTotal > 0 
ORDER BY VendorName DESC; 

但我得到这个错误:

Msg 102, Level 15, State 1, Line 6 Incorrect syntax near ')'.

即使是最轻微的援助将是非常有帮助....谢谢。

+1

这气味像功课做我不会放弃一个完整的答案,但是,1)检查你在where子句中过滤的内容,2)查看case语句的语法,3)将所有'IIF'语句放在同一行,你应该看到你的问题。 – JRLambert

+1

第二个查询:您的CASE语法错误。应CASE WHEN .....的CASE – Squirrel

+0

@Squirrel后除去InvoiceTotal:在“END谢谢,仍然错误,PotentialDiscount” 'SELECT VENDORNAME,InvoiceNumber,InvoiceTotal,PotentialDiscount = CASE WHEN InvoiceTotal <100 THEN '不考虑折扣' WHEN InvoiceTotal = 101-500 THEN '折扣潜在3' WHEN InvoiceTotal> 501-1000 THEN '折扣潜在2' WHEN InvoiceTotal> 1000 THEN '折扣潜在1' END,PotentialDiscount 从供应商处注册发票 ON Vendors.VendorID = Invoices.VendorID ORDER BY InvoiceTotal;' – Pau808

回答

0

查询1

貌似你是比较InvoiceDate到132,而你需要的是InvoiceAge。他指出,你不能在WHERE谓词同一个查询的直接使用新创建的别名,你要么需要重复where子句中全DATEDIFF表达:

AND DATEDIFF(day, '2008-01-12', InvoiceDate) > 132 

您还可以通过包装节省重复派生表或CTE,例如

WITH InvoiceCte AS 
(
    SELECT VendorName, InvoiceTotal, InvoiceDate, 
      DATEDIFF(day, '2008-01-12', InvoiceDate) AS InvoiceAge, 
      InvoiceTotal - PaymentTotal - CreditTotal AS InvoiceNett 
    FROM Vendors JOIN Invoices 
     ON Vendors.VendorID = Invoices.VendorID 
) 
SELECT * FROM InvoiceCte 
WHERE InvoiceNett > 0 
     AND InvoiceAge > 132 
ORDER BY VendorName; 

还注意到DATEDIFFDATEDIFF (datepart , startdate , enddate),也会建议使用ISO 8601风格的日期格式,以防止对当地的日期格式混乱)。

查询2

正如其他人所说,你不能使用CASE x WHEN y THEN z语法数据的范围。您需要改用CASE WHEN condition THEN格式。另外,注意到,案件将在第一只匹配,您可以通过简化的目的在于消除在范围内的差距:

SELECT VendorName, InvoiceNumber, InvoiceTotal, 
    CASE 
    WHEN InvoiceTotal < 100 THEN 'No discount consideration' 
    WHEN InvoiceTotal < 500 THEN 'Discount potential 3' 
    WHEN InvoiceTotal < 1000 THEN 'Discount potential 2' 
    ELSE 'Discount potential 1' 
    END AS PotentialDiscount 
FROM Vendors JOIN Invoices 
    ON Vendors.VendorID = Invoices.VendorID 
ORDER BY InvoiceTotal; 

查询3

像第一次查询,你就可以为了防止带有CTE或派生表的重复的SUM(InvoiceTotal),和第二个查询一样,嵌套的IIF's也只需要检查下限,因为上限将由前面的嵌套处理。

您还需要将连接条件修复为ON Vendors.VendorID = Invoices.VendorId。我假设“低”是后备的分类,否则你会提供最后IIF的附加价值,如果Low不满足条件:

WITH MyCte AS 
(
    SELECT 
     VendorName, SUM(InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue, 
     SUM(InvoiceTotal) AS SumInvoiceTotal 
    FROM Vendors 
     JOIN Invoices 
     ON Vendors.VendorID = Invoices.VendorId 
    WHERE InvoiceTotal > 0 
    GROUP BY VendorName 
) 
SELECT VendorName, BalanceDue, SumInvoiceTotal, 
    IIF(SumInvoiceTotal > 11000, 'Very high', 
     IIF(SumInvoiceTotal > 500, 'High', 
      IIF(SumInvoiceTotal > 200, 'Medium', 
       'Low'))) AS DebtLevel 
FROM MyCte 
    ORDER BY VendorName DESC;