如果连接存在,则从连接表返回值

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 来指定您想要的哪个价格——最小的、最旧的、最新的或由其他方法确定的优先级。

【讨论】:

以上是关于如果连接存在,则从连接表返回值的主要内容,如果未能解决你的问题,请参考以下文章

如果某个字段值出现在另一个表中,则从一个表中排除记录

比较内连接和外连接 SQL 语句

如果值存在于多个表中,则从表中获取结果

如果值等于,则从对象返回键和值

连接多个表返回 NULL 值

如果值等于,则从对象返回键和值