SQL 有条件的查询
SQL query with condition
所以我的销售订单中的每件商品都有一个 table,其中包含商品 ID 或仅包含描述(如果它不是真实商品),table 如下所示:
销售订单行:
|ID | SOI_IMA_RecordID | SOI_LineNbrTypeCode | SOI_MiscLineDescription |
|1 | 2 | Item | XYZ |
|2 | NULL | GL Acct | Description |
|3 | NULL | GL Acct | Descrip |
|4 | 20 | Item | ABC |
我想做的是,如果它不是真实的项目(有 SOI_IMA_RecordID = NULL and/or SOI_LineNbrTypeCode = GL Acct)不要与我的项目进行内部连接 table 并获取 SOI_MiscLineDescription 而不是项目名称(在我的查询中为 IMA_ItemName)。
我的查询如下:
SELECT SOH_ModifiedDate,
SOM_SalesOrderID,
IMA_ItemName,
SOH_SOD_RequiredDate,
SOD_RequiredDate,
SOH_SOD_DockDate,
SOD_DockDate,
SOH_SOD_PromiseDate,
SOD_PromiseDate,
SOH_SOD_RequiredQty,
SOD_RequiredQty,
SOH_SOD_UnitPrice,
SOD_UnitPrice
FROM WSI_SOH SOH
INNER JOIN SalesOrderDelivery SOD ON SOH.SOH_SOD_RecordID = SOD.SOD_RecordID
INNER JOIN SalesOrder SO ON SO.SOM_RecordID = SOD.SOD_SOM_RecordID
INNER JOIN SalesOrderLine SOI ON SOI.SOI_RecordID = SOD.SOD_SOI_RecordID
INNER JOIN Item ITE ON ITE.IMA_RecordID = SOI.SOI_IMA_RecordID
怎么做?
您可以在 SELECT
:
中使用 CASE
语句
SELECT CASE WHEN SOI_IMA_RecordID IS NULL OR
SOI_LineNbrTypeCode = 'GL Acct'
THEN SOI_MiscLineDescription
ELSE IMA_ItemName
END ItemName,
-- ...
FROM WSI_SOH SOH
INNER JOIN SalesOrderDelivery SOD ON SOH.SOH_SOD_RecordID = SOD.SOD_RecordID
INNER JOIN SalesOrder SO ON SO.SOM_RecordID = SOD.SOD_SOM_RecordID
INNER JOIN SalesOrderLine SOI ON SOI.SOI_RecordID = SOD.SOD_SOI_RecordID
LEFT JOIN Item ITE ON ITE.IMA_RecordID = SOI.SOI_IMA_RecordID AND
SOI_IMA_RecordID IS NOT NULL AND
SOI_LineNbrTypeCode != 'GL Acct'
A left join
将允许您在匹配 on
条件时加入,并且在不匹配时仍然仅显示加入右侧的列 - 在您的情况下,当 SOI_IMA_RecordID
是 null
:
SELECT SOH_ModifiedDate,
SOM_SalesOrderID,
IMA_ItemName,
SOH_SOD_RequiredDate,
SOD_RequiredDate,
SOH_SOD_DockDate,
SOD_DockDate,
SOH_SOD_PromiseDate,
SOD_PromiseDate,
SOH_SOD_RequiredQty,
SOD_RequiredQty,
SOH_SOD_UnitPrice,
SOD_UnitPrice
FROM WSI_SOH SOH
INNER JOIN SalesOrderDelivery SOD ON SOH.SOH_SOD_RecordID = SOD.SOD_RecordID
INNER JOIN SalesOrder SO ON SO.SOM_RecordID = SOD.SOD_SOM_RecordID
INNER JOIN SalesOrderLine SOI ON SOI.SOI_RecordID = SOD.SOD_SOI_RecordID
LEFT JOIN Item ITE ON ITE.IMA_RecordID = SOI.SOI_IMA_RecordID
将您的 INNER JOIN
更改为 LEFT JOIN
并使用 CASE
获得您想要的值:
SELECT SOH_ModifiedDate,
...
CASE
WHEN IMA_ItemName IS NULL THEN SOI_MiscLineDescription
ELSE IMA_ItemName END AS ItemName,
...
FROM WSI_SOH SOH
...
LEFT JOIN Item ITE ON ITE.IMA_RecordID = SOI.SOI_IMA_RecordID AND SOI_IMA_RecordID IS NOT NULL
这样只有在有记录匹配时才加入Item
table,没有匹配记录时字段为NULL
。当 CASE
不是 NULL
时,CASE
从 Item
table 中选择字段,否则选择描述。
编辑 - 我在输入答案时看到有两个人比我先到了!
因为您正在对项目使用 INNER JOIN,所以您的 SalesOrderLine 中没有相应 ITE.IMA_RecordID 的任何行都不会出现在您的最终查询中。
相反,对项目使用 LEFT JOIN,并使用确定要使用哪个描述的函数,或者简单地 return 两列(销售订单行的描述和项目的描述。)
我不太熟悉 SQL 服务器函数,但在 PostGres 和 MySql 中,这些函数就像 COALESCE() (return 中的第一个非空值字段列表)
我相信你可能想在这里使用 case 语句,比如
case when item.description!=null
then item.description
else SalesOrderLine.SOI_MiscLineDescription
end
所以我的销售订单中的每件商品都有一个 table,其中包含商品 ID 或仅包含描述(如果它不是真实商品),table 如下所示:
销售订单行:
|ID | SOI_IMA_RecordID | SOI_LineNbrTypeCode | SOI_MiscLineDescription |
|1 | 2 | Item | XYZ |
|2 | NULL | GL Acct | Description |
|3 | NULL | GL Acct | Descrip |
|4 | 20 | Item | ABC |
我想做的是,如果它不是真实的项目(有 SOI_IMA_RecordID = NULL and/or SOI_LineNbrTypeCode = GL Acct)不要与我的项目进行内部连接 table 并获取 SOI_MiscLineDescription 而不是项目名称(在我的查询中为 IMA_ItemName)。
我的查询如下:
SELECT SOH_ModifiedDate,
SOM_SalesOrderID,
IMA_ItemName,
SOH_SOD_RequiredDate,
SOD_RequiredDate,
SOH_SOD_DockDate,
SOD_DockDate,
SOH_SOD_PromiseDate,
SOD_PromiseDate,
SOH_SOD_RequiredQty,
SOD_RequiredQty,
SOH_SOD_UnitPrice,
SOD_UnitPrice
FROM WSI_SOH SOH
INNER JOIN SalesOrderDelivery SOD ON SOH.SOH_SOD_RecordID = SOD.SOD_RecordID
INNER JOIN SalesOrder SO ON SO.SOM_RecordID = SOD.SOD_SOM_RecordID
INNER JOIN SalesOrderLine SOI ON SOI.SOI_RecordID = SOD.SOD_SOI_RecordID
INNER JOIN Item ITE ON ITE.IMA_RecordID = SOI.SOI_IMA_RecordID
怎么做?
您可以在 SELECT
:
CASE
语句
SELECT CASE WHEN SOI_IMA_RecordID IS NULL OR
SOI_LineNbrTypeCode = 'GL Acct'
THEN SOI_MiscLineDescription
ELSE IMA_ItemName
END ItemName,
-- ...
FROM WSI_SOH SOH
INNER JOIN SalesOrderDelivery SOD ON SOH.SOH_SOD_RecordID = SOD.SOD_RecordID
INNER JOIN SalesOrder SO ON SO.SOM_RecordID = SOD.SOD_SOM_RecordID
INNER JOIN SalesOrderLine SOI ON SOI.SOI_RecordID = SOD.SOD_SOI_RecordID
LEFT JOIN Item ITE ON ITE.IMA_RecordID = SOI.SOI_IMA_RecordID AND
SOI_IMA_RecordID IS NOT NULL AND
SOI_LineNbrTypeCode != 'GL Acct'
A left join
将允许您在匹配 on
条件时加入,并且在不匹配时仍然仅显示加入右侧的列 - 在您的情况下,当 SOI_IMA_RecordID
是 null
:
SELECT SOH_ModifiedDate,
SOM_SalesOrderID,
IMA_ItemName,
SOH_SOD_RequiredDate,
SOD_RequiredDate,
SOH_SOD_DockDate,
SOD_DockDate,
SOH_SOD_PromiseDate,
SOD_PromiseDate,
SOH_SOD_RequiredQty,
SOD_RequiredQty,
SOH_SOD_UnitPrice,
SOD_UnitPrice
FROM WSI_SOH SOH
INNER JOIN SalesOrderDelivery SOD ON SOH.SOH_SOD_RecordID = SOD.SOD_RecordID
INNER JOIN SalesOrder SO ON SO.SOM_RecordID = SOD.SOD_SOM_RecordID
INNER JOIN SalesOrderLine SOI ON SOI.SOI_RecordID = SOD.SOD_SOI_RecordID
LEFT JOIN Item ITE ON ITE.IMA_RecordID = SOI.SOI_IMA_RecordID
将您的 INNER JOIN
更改为 LEFT JOIN
并使用 CASE
获得您想要的值:
SELECT SOH_ModifiedDate,
...
CASE
WHEN IMA_ItemName IS NULL THEN SOI_MiscLineDescription
ELSE IMA_ItemName END AS ItemName,
...
FROM WSI_SOH SOH
...
LEFT JOIN Item ITE ON ITE.IMA_RecordID = SOI.SOI_IMA_RecordID AND SOI_IMA_RecordID IS NOT NULL
这样只有在有记录匹配时才加入Item
table,没有匹配记录时字段为NULL
。当 CASE
不是 NULL
时,CASE
从 Item
table 中选择字段,否则选择描述。
编辑 - 我在输入答案时看到有两个人比我先到了!
因为您正在对项目使用 INNER JOIN,所以您的 SalesOrderLine 中没有相应 ITE.IMA_RecordID 的任何行都不会出现在您的最终查询中。
相反,对项目使用 LEFT JOIN,并使用确定要使用哪个描述的函数,或者简单地 return 两列(销售订单行的描述和项目的描述。)
我不太熟悉 SQL 服务器函数,但在 PostGres 和 MySql 中,这些函数就像 COALESCE() (return 中的第一个非空值字段列表)
我相信你可能想在这里使用 case 语句,比如
case when item.description!=null
then item.description
else SalesOrderLine.SOI_MiscLineDescription
end