如果连接存在,则从连接表返回值
Posted
技术标签:
【中文标题】如果连接存在,则从连接表返回值【英文标题】:If join exists then return value from join table 【发布时间】:2019-02-10 09:11:20 【问题描述】:我有两张表,下面有列
库存:
Id Name Price
1 Item1 1€
还有桌子
库存价格:
Id Price
1 2€
我只想为每个项目选择一行。 如果存在连接,那么我需要从我的第一个表“Inventory”中选择“InventoryPrices”中的价格。到目前为止,如果“InventoryPrices”与第一个表“Inventory”连接,它会为每个 ID 返回两行。
如何检查 join 是否不为空,然后显示第二个表价格的一行
【问题讨论】:
我不明白。如果Inventory
中的库存 ID 1 有一行,InventoryPrices
中的库存 ID 1 有一行,并且您加入了库存 ID,那么您仍然有一个结果行而不是两个。请出示您的查询。
在您给出的示例中,我们在两个表中都没有每个 id 的 2 条记录,那么您如何在输出中为每个 id 获取 2 条记录
【参考方案1】:
要检查 InventoryPrices
表中是否存在记录,您需要使用 LEFT JOIN
要为每个 Id 获取一行,您可以使用 ROW_NUMBER()
如下查询。
SELECT *
from
(
SELECT t1.id,
t1.NAME,
COALESCE(t2.price,t1.price) AS price ,
Row_number() OVER(partition BY t1.id ORDER BY t1.id) rn
FROM inventory t1
LEFT JOIN inventoryprices t2
ON t1.id=t2.id
) t
WHERE t.rn=1
【讨论】:
在这个例子中,我在 t1.id=t2.id ) t 之后得到错误语法 列名“rn”无效。 我忘记将 rn 移动到内表,我已经更正了,它现在应该可以工作了。 它工作!谢谢,如果我也使用 where 语句可以吗? 你需要把它放在“ON t1.id=t2.id AND t2.CatalogID =3”而不是放在哪里。如果要过滤左连接中的记录,则需要将条件放在连接条件本身上,而不是放在完整的位置上。【参考方案2】:您可以使用以下查询:
WITH CTE_1 AS (
SELECT T1.ID, T1.Name,
CASE WHEN T2.Price is NOT NULL THEN T2.Price ELSE T1.Price END as [Price],
ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ID) as rn
FROM Inventory T1
LEFT JOIN InventoryPrices T2
ON T1.ID = T2.ID)
SELECT * FROM CTE_1 WHERE rn = 1
【讨论】:
【参考方案3】:outer apply
-- 它实现了一种称为“横向连接”的东西 -- 完全符合您的要求:
select t1.id, t1.name, coalesce(t2.price, t1.price)
from t1 outer apply
(select top (1) t2.*
from t2
where t2.id = t1.id
) t2;
通常,子查询会有一个order by
来指定您想要的哪个价格——最小的、最旧的、最新的或由其他方法确定的优先级。
【讨论】:
以上是关于如果连接存在,则从连接表返回值的主要内容,如果未能解决你的问题,请参考以下文章