我不确定如何将其从 Access 转换为 SQL。我们目前正在使用 SQL Server 2008。我正在尝试将 Access 报告迁移到 SQL 视图中。
SELECT
First(IIf(IsNull([dbo_CUST_ADDRESS]![STATE]),IIf(IsNull([dbo_CUSTOMER]![BILL_TO_STATE]),[dbo_CUSTOMER]![STATE],[dbo_CUSTOMER]![BILL_TO_STATE]),[dbo_CUST_ADDRESS]![STATE])) AS STATE
, dbo_RECEIVABLE.INVOICE_ID
, dbo_RECEIVABLE.INVOICE_DATE
, dbo_RECEIVABLE.CUSTOMER_ID
, First(IIf(IsNull([dbo_CUST_ADDRESS]![NAME]),IIf(IsNull([dbo_CUSTOMER]![BILL_TO_NAME]),[dbo_CUSTOMER]![NAME],[dbo_CUSTOMER]![BILL_TO_NAME]),[dbo_CUST_ADDRESS]![NAME])) AS COMPANY
, Sum(IIf([dbo_RECEIVABLE_LINE]![GL_ACCOUNT_ID]='4005-008',0,[dbo_RECEIVABLE_LINE]![AMOUNT])) AS Inv_Total_Amt
, Sum(IIf([dbo_RECEIVABLE_LINE]![REFERENCE]<>"LA-COUNTY" And [dbo_RECEIVABLE_LINE]![REFERENCE]<>"FREIGHT" And [dbo_RECEIVABLE_LINE]![GL_ACCOUNT_ID]<>'4005-008',[dbo_RECEIVABLE_LINE]![AMOUNT],0)) AS Subtotal
, Sum(IIf([dbo_RECEIVABLE_LINE]![REFERENCE]="LA-COUNTY",[dbo_RECEIVABLE_LINE]![AMOUNT],0)) AS TAX
, Sum(IIf([dbo_RECEIVABLE_LINE]![REFERENCE]="FREIGHT",[dbo_RECEIVABLE_LINE]![AMOUNT],0)) AS Freight
, dbo_RECEIVABLE.SALESREP_ID
FROM (((dbo_RECEIVABLE RIGHT JOIN dbo_RECEIVABLE_LINE ON dbo_RECEIVABLE.INVOICE_ID = dbo_RECEIVABLE_LINE.INVOICE_ID) LEFT JOIN dbo_CUSTOMER_ORDER ON dbo_RECEIVABLE_LINE.CUST_ORDER_ID = dbo_CUSTOMER_ORDER.ID) LEFT JOIN dbo_CUST_ADDRESS ON (dbo_CUSTOMER_ORDER.CUSTOMER_ID = dbo_CUST_ADDRESS.CUSTOMER_ID) AND (dbo_CUSTOMER_ORDER.SHIP_TO_ADDR_NO = dbo_CUST_ADDRESS.ADDR_NO)) LEFT JOIN dbo_CUSTOMER ON dbo_RECEIVABLE.CUSTOMER_ID = dbo_CUSTOMER.ID
GROUP BY
dbo_RECEIVABLE.INVOICE_ID
, dbo_RECEIVABLE.INVOICE_DATE
, dbo_RECEIVABLE.CUSTOMER_ID
, dbo_RECEIVABLE.SALESREP_ID
ORDER BY
First(IIf(IsNull([dbo_CUST_ADDRESS]![STATE]),IIf(IsNull([dbo_CUSTOMER]![BILL_TO_STATE]),[dbo_CUSTOMER]![STATE],[dbo_CUSTOMER]![BILL_TO_STATE]),[dbo_CUST_ADDRESS]![STATE]))
, dbo_RECEIVABLE.INVOICE_ID;
Run Code Online (Sandbox Code Playgroud)
这是我在 2015 年 10 月 21 日创建的内容。我更改了 WHERE 以查找发票编号以对其进行测试并添加嵌套 CASE。它显示了该发票的 2 行,并且没有将它们分组为 1。
选择
(SELECT TOP 1 CASE WHEN CUST_ADDRESS.STATE is NULL THEN CASE WHEN CUSTOMER.BILL_TO_STATE is NULL THEN CUSTOMER.STATE ELSE CUSTOMER.BILL_TO_STATE END ELSE CUST_ADDRESS.STATE END FROM dbo.RECEIVABLE RECEIVABLE ERIVEINABLE dbo.RECEIVABLE . dbo.RECEIVABLE_LINE.INVOICE_ID LEFT OUTER JOIN dbo.CUSTOMER_ORDER ON dbo.RECEIVABLE_LINE.CUST_ORDER_ID = dbo.CUSTOMER_ORDER.ID LEFT OUTER JOIN dbo.CUST_ADDRESS ON dbo.CUSTOMER.CUST_ORDER_Dbo.CUSTOMER.CUST_ORDER_ID = dbo.CUSTOMER.CUST_ORDER_Dbo.CUSTOMER. CUST_ADDRESS。ADDR_NO LEFT OUTER JOIN dbo.CUSTOMER ON dbo.RECEIVABLE.CUSTOMER_ID = dbo.CUSTOMER.ID WHERE dbo.RECEIVABLE.INVOICE_ID = 'iv184546') 作为状态, dbo.RECEIVABLE.RECINVOICE_ID,IVABLE_DBOICEDVOICE_ID. , dbo.RECEIVABLE.CUSTOMER_ID, (SELECT TOP 1 CASE WHEN dbo.CUST_ADDRESS.NAME 为 NULL THEN dbo.CUSTOMER.NAME ELSE dbo.CUST_ADDRESS.NAME END FROM dbo.RECEIVABLE RIGHT OUTER JOIN dbo.RECEIVABLEDLINE_VOIN dbo.RECEIVABLE_LINE.INVOICE_ID LEFT OUTER JOIN dbo.CUSTOMER_ORDER ON dbo.RECEIVABLE_LINE.CUST_ORDER_ID = dbo.CUSTOMER_ORDER。ID LEFT OUTER JOIN dbo.CUST_ADDRESS ON dbo.CUSTOMER_ORDER.CUSTOMER_ID = dbo.CUST_ADDRESS.CUSTOMER_ID AND dbo.CUSTOMER_ORDER.SHIP_TO_ADDR_NO = dbo.CUST_ADDRESS.RECADDR_NO LEFTINSTOMER_ORDER.CUSTOMER_ID = dbo.CUST_ADDRESS.CUSTOMER_ID dbo.RECEIVABLE.INVOICE_ID = 'iv184546') AS COMPANY, SUM(CASE WHEN RECEIVABLE_LINE.GL_ACCOUNT_ID = '4005-008' THEN 0 ELSE RECEIVABLE_LINE.AMOUNT END) AS Inv_Total_Amt, SUM-CASE WHEN CASE ' AND RECEIVABLE_LINE.REFERENCE <> 'FREIGHT' AND RECEIVABLE_LINE.GL_ACCOUNT_ID <> '4005-008' THEN RECEIVABLE_LINE.AMOUNT ELSE 0 END) 作为小计,SUM(CASE WHEN RECEIVABLE_LINE.REFERENCE = 'LA-COUNTY' THEN RECEIVABLE_LINE.AMOUNT ELSE 0 END)作为税款,SUM(CASE WHEN RECEIVABLE_LINE.REFERENCE = 'FREIGHT' THEN RECEIVABLE_LINE.AMOUNT ELSE 0 END。作为税款) SALESREP_ID
从 dbo.RECEIVABLE RIGHT OUTER JOIN dbo.RECEIVABLE_LINE ON dbo.RECEIVABLE.INVOICE_ID = dbo.RECEIVABLE_LINE.INVOICE_ID LEFT OUTER JOIN dbo.CUSTOMER_ORDER ON dbo.RECEIVABLE_LINEID.CUST_ORDERdbo.RECEIVABLE_LINEID.CUST_ORDERDBOFTA.CUST_ORDERdbo.RECEIVABLE_LINE.INVOICE_ID .CUSTOMER_ID = dbo.CUST_ADDRESS.CUSTOMER_ID AND dbo.CUSTOMER_ORDER.SHIP_TO_ADDR_NO = dbo.CUST_ADDRESS.ADDR_NO LEFT OUTER JOIN dbo.CUSTOMER ON dbo.RECEIVABLE.CUSTOMER_ID = .dboID6E4MER_ID=.dboID6E4MER_IDBOE4MER_4MERICUSTOMER_IDABLEIVECUID6 CUST_ADDRESS.STATE 为 NULL 时的情况 CUSTOMER.BILL_TO_STATE 为 NULL 时的情况则 CUSTOMER.STATE ELSE 客户。BILL_TO_STATE END ELSE CUST_ADDRESS.STATE END, dbo.CUSTOMER.NAME, dbo.RECEIVABLE.INVOICE_ID, dbo.RECEIVABLE.INVOICE_DATE, dbo.RECEIVABLE.POSTING_DATE, dbo.RECEIVABLE.CUSTOMER_SREIVABLEd.CUSTOM.INVOICE_ID, dbo.RECEIVABLE.INVOICE_DATE. NAME IS NULL THEN dbo.CUSTOMER.NAME ELSE dbo.CUST_ADDRESS.NAME END当 dbo.CUST_ADDRESS.NAME 为 NULL 时的情况,则 dbo.CUSTOMER.NAME ELSE dbo.CUST_ADDRESS.NAME END当 dbo.CUST_ADDRESS.NAME 为 NULL 时的情况,则 dbo.CUSTOMER.NAME ELSE dbo.CUST_ADDRESS.NAME END
ORDER BY dbo.RECEIVABLE.INVOICE_ID, dbo.RECEIVABLE.INVOICE_DATE;
而不是重写整个查询,我会给你一些关于如何做的提示:
IIf(condition, a, b)
变成: CASE WHEN condition THEN a ELSE b END
IsNull(x)
变成: x IS NULL
IIf(IsNull(x), y, x))
然后可以将组合写为:
CASE WHEN x IS NULL THEN y ELSE x END
并进一步简化为COALESCE(x, y)
。[tab]![col]
变为:[tab].[col]
如果名称未保留,则更具可读性:tab.col
"FREIGHT"
为'FREIGHT'
。双引号在标准 SQL(以及 SQL Server 中,除了括号之外)用于引用表和列的名称和别名,而不是用于文字。FROM
可以安全地删除子句中的括号。SQL Server 的解析器不管有没有它们都很满意。此外,如果您为表使用别名,可读性会增加:
FROM (((dbo_RECEIVABLE RIGHT JOIN dbo_RECEIVABLE_LINE ON dbo_RECEIVABLE.INVOICE_ID = dbo_RECEIVABLE_LINE.INVOICE_ID) LEFT JOIN dbo_CUSTOMER_ORDER ON dbo_RECEIVABLE_LINE.CUST_ORDER_ID = dbo_CUSTOMER_ORDER.ID) LEFT JOIN dbo_CUST_ADDRESS ON (dbo_CUSTOMER_ORDER.CUSTOMER_ID = dbo_CUST_ADDRESS.CUSTOMER_ID) AND (dbo_CUSTOMER_ORDER.SHIP_TO_ADDR_NO = dbo_CUST_ADDRESS.ADDR_NO)) LEFT JOIN dbo_CUSTOMER ON dbo_RECEIVABLE.CUSTOMER_ID = dbo_CUSTOMER.ID
Run Code Online (Sandbox Code Playgroud)
变成:
FROM dbo_RECEIVABLE
RIGHT JOIN dbo_RECEIVABLE_LINE
ON dbo_RECEIVABLE.INVOICE_ID = dbo_RECEIVABLE_LINE.INVOICE_ID
LEFT JOIN dbo_CUSTOMER_ORDER
ON dbo_RECEIVABLE_LINE.CUST_ORDER_ID = dbo_CUSTOMER_ORDER.ID
LEFT JOIN dbo_CUST_ADDRESS
ON dbo_CUSTOMER_ORDER.CUSTOMER_ID = dbo_CUST_ADDRESS.CUSTOMER_ID
AND dbo_CUSTOMER_ORDER.SHIP_TO_ADDR_NO = dbo_CUST_ADDRESS.ADDR_NO
LEFT JOIN dbo_CUSTOMER
ON dbo_RECEIVABLE.CUSTOMER_ID = dbo_CUSTOMER.ID
Run Code Online (Sandbox Code Playgroud)
进而:
FROM dbo_RECEIVABLE AS rec
RIGHT JOIN dbo_RECEIVABLE_LINE AS line
ON rec.INVOICE_ID = line.INVOICE_ID
LEFT JOIN dbo_CUSTOMER_ORDER AS ord
ON line.CUST_ORDER_ID = ord.ID
LEFT JOIN dbo_CUST_ADDRESS AS addr
ON ord.CUSTOMER_ID = addr.CUSTOMER_ID
AND ord.SHIP_TO_ADDR_NO = addr.ADDR_NO
LEFT JOIN dbo_CUSTOMER AS cust
ON rec.CUSTOMER_ID = cust.ID
Run Code Online (Sandbox Code Playgroud)
相应地调整SELECT
和中的所有引用GROUP BY
。
在ORDER BY
你可以使用包含或定义的列别名SELECT
列表。无需重复复杂的表达式或表别名:
ORDER BY STATE, INVOICE_ID; ;
Run Code Online (Sandbox Code Playgroud)顺便说RIGHT JOIN
一下,这看起来不对。特别是因为GROUP BY
是基于可为空的侧列(dbo_RECEIVABLE
表)。它可能应该是INNER
或LEFT JOIN
。
该First()
功能是最困难的部分。你可以用MIN()
or替换它,MAX()
但你可能不会得到相同的结果,并且可能无法在所有查询中使用这个技巧,只有那些带有GROUP BY
.
等价物将非常复杂,使用其中之一ROW_NUMBER()
并更改整个查询的结构(将其包装在派生表或 CTE 中并将其GROUP BY
从内部级别移动到外部级别)。在 2012+ 版本中,FIRST_VALUE()
也可能会使用该功能。
归档时间: |
|
查看次数: |
145 次 |
最近记录: |