使用逗号分隔列表连接表

时间:2014-03-21 04:58:10

标签: sql sql-server

SELECT * 
FROM  Products, 
      ProductDetails 
WHERE Products.ProductID  IN (111,222,333,444,555) 
AND Products.ProductID    =  ProductDetails.ProductID 

我当前的SQL与上面的类似。现在,有一个新的要求,我希望逗号分隔列表中的ProductID仍然可以在记录集中使用,即使它在Products和ProductDetails表中找不到。

我该怎么做?也许可以使用LEFT JOIN实现这一点?我对SQL并不是很擅长,希望有人可以帮助处理工作代码。

感谢。

5 个答案:

答案 0 :(得分:3)

我建议您创建一个'表值函数',它会从逗号单独的字符串中返回基于表的结果集

CREATE FUNCTION [dbo].[funcSplit]
(
    @param      NVARCHAR(MAX),
    @delimiter  CHAR(1)
)
RETURNS @t TABLE (val NVARCHAR(MAX))
AS
BEGIN
    SET @param += @delimiter

    ;WITH a AS
    (
        SELECT CAST(1 AS BIGINT) f,
               CHARINDEX(@delimiter, @param) t,
               1 seq
        UNION ALL
        SELECT t + 1,
               CHARINDEX(@delimiter, @param, t + 1),
               seq + 1
        FROM   a
        WHERE  CHARINDEX(@delimiter, @param, t + 1) > 0
    )
    INSERT @t
    SELECT SUBSTRING(@param, f, t - f)         
    FROM   a
           OPTION(MAXRECURSION 0)

    RETURN
END

并使用LEFT JOIN,因此您将始终从第一个查询获得结果集,这是您的输入字符串,其中包含产品ID,下面是一个示例查询。 (您不需要编写存储过程,只需使用查询,并在@str变量中传递ProductIds。)

DECLARE @str nvarchar(MAX)
SET @str='111,222,333,444,555'

SELECT val , p.ProductID, pd.ProductID from dbo.[funcSplit](@str,',')  a
LEFT JOIN Products p ON p.ProductID=a.val
LEFT JOIN ProductDetails pd ON pd.ProductID=a.val

您将获得类似

的输出
val p.ProductID pd.ProductID
111 111      NULL
222 222      222
333 333      NULL
444 NULL     NULL

希望这会奏效!

由于 苏雷什

答案 1 :(得分:2)

在这种情况下,您的IN条款对您无效。您必须提供包含ID的表。已经介绍了一种方法:UDF将逗号分隔列表转换为表格。

还有另一种非常简单的方法可以获得你想要的东西:

select * 
  from (
         SELECT * FROM (VALUES(111),(222),(333),(444),(555)) as x(ID)
        ) x 
        left join Products on x.ID = Products.ID 
        left join ProductDetails 
          on Products.ProductID = ProductDetails.ProductID 

列出列表中的所有ID。如果匹配Product,它将列出该产品。如果该产品有ProductDetails,它会列出这些详细信息。

答案 2 :(得分:0)

尝试左连接,

;With CTE as
(
select 111 as a
Union All
select 222
Union All
select 333
Union All
select 444
Union All
select 555
)
Select CTE.*,P.*, PD.*  from CTE
left join Products P on P.ProductID =CTE.a
left join ProductDetails PD 
ON 
    P.ProductID = PD.ProductID 
WHERE 
    CTE.a IN (111,222,333,444,555)

答案 3 :(得分:0)

左连接应该有效。我已创建样本并执行它正在工作。它显示所有产品,即使它在ProductDetail中也不存在。

 select p.*,pd.* from Product p left join 
 ProductDetails pd  on (p.id = pd.ProductId) where
 p.id in (1,2,3,5)

产品清单

enter image description here

产品详情清单

enter image description here

以上查询的查询结果为

enter image description here

答案 4 :(得分:-1)

请尝试以下查询。

SELECT 
    P.*, PD.* 
FROM 
    Products P inner join ProductDetails PD 
ON 
    P.ProductID = PD.ProductID 
WHERE 
    P.ProductID IN (111,222,333,444,555)

如果您需要更多详细信息,请与我们联系。