如何在 where 子句中加入具有动态结果的两行或多行?

How to join Two or more row with dynamic result in where clause?

我正在尝试在 table 中 EntityId 相等的条件下使用 COALESCE 连接两行或三行,以便我的输出如下所示:

EmailAddress                         EntityId

12_abc@abc.com::::13_pqr@pqr.com     101
12_koi@koi.com::::13_poi@poi.com     102

现在,根据我的查询,我得到以下结果:

EmailAddress   EmailTypeId     EntityId

abc@abc.com    12              101
pqr@pqr.com    13              101
koi@koi.com    12              102
poi@poi.com    13              102

我使用的查询如下:

DECLARE @MyTableVariable TABLE
(

  EmailAddress nvarchar(250),
  EntityIDE int
);

INSERT @MyTableVariable(
  EmailAddress,
  EntityIDE
 )

SELECT  concat([EmailTypeID], '_____', [EmailAddress]))), [EntityID]
FROM [dbo].[Email_Addresses] where [EntityID] in 

(select [EntityID] from [Entities] where [SourcePrimaryKey] in 
    (select [MerchantOwnerID] from [dbo].[Merchant_Owners] where [MerchantID] = 1 ) and
    [EntityTypeID] = (select [EntityTypeID] from [Entity_Types] where [EntityType] = 'MerchantOwner'))

select * from @MyTableVariable

我定义了一个 table 值参数,在我的 select 查询中,我将两列合并为一列,但我不知道如何使用 coalesce 连接两个或多个EntityId 相同的行。

我在 where return 列表 EntityId

之后的查询
(select [EntityID] from [Entities] where [SourcePrimaryKey] in 
    (select [MerchantOwnerID] from [dbo].[Merchant_Owners] where [MerchantID] = 1 ) and
    [EntityTypeID] = (select [EntityTypeID] from [Entity_Types] where [EntityType] = 'MerchantOwner'))

上面的查询 returns 下面的结果集

EntityId

101
102
103
104
...

编辑

; WITH CTE AS (
    SELECT EA.[EmailTypeID], EA.[EmailAddress], EA.[EntityID]
    FROM [dbo].[Email_Addresses] EA
    JOIN [Entities] E ON E.[EntityID] = EA.[EntityID]
    JOIN (SELECT [MerchantOwnerID] FROM [dbo].[Merchant_Owners] WHERE [MerchantID] = 1) M ON M.[MerchantOwnerID] = E.[SourcePrimaryKey]
    JOIN (SELECT [EntityTypeID] FROM [Entity_Types] WHERE [EntityType] = 'MerchantOwner') ET ON ET.[EntityTypeID] = E.[EntityTypeID])
    ,
    ABC
    As
    (
    SELECT EB.[PhoneNumber], EB.[EntityID], EB.[PhoneType]
    FROM [dbo].[Phones] EB
    JOIN [Entities] E ON E.[EntityID] = EB.[EntityID]
    JOIN (SELECT [MerchantOwnerID] FROM [dbo].[Merchant_Owners] WHERE [MerchantID] = 1) M ON M.[MerchantOwnerID] = E.[SourcePrimaryKey]
    JOIN (SELECT [EntityTypeID] FROM [Entity_Types] WHERE [EntityType] = 'MerchantOwner') ET ON ET.[EntityTypeID] = E.[EntityTypeID]
    )
SELECT STUFF((SELECT '::::' + CONVERT(NVARCHAR, [EmailTypeID]) + '_' + [EmailAddress]
            FROM CTE
            WHERE [EntityID] = T1.[EntityID]
            ORDER BY [EmailTypeID]
            FOR XML PATH ('')),1,4,'') [EmailAddress],
            T1.[EntityID],
            STUFF((SELECT '::::' + CONVERT(NVARCHAR, [PhoneType]) + '_' + [PhoneNumber]
            FROM ABC
            WHERE [EntityID] = T2.[EntityID]
            ORDER BY [PhoneType]
            FOR XML PATH ('')),1,4,'') [PhoneNumber],
            T2.[EntityID] 

FROM CTE T1, ABC T2
GROUP BY T1.[EntityID],T2.[EntityID]

这个结果给了我 56 行 我的一个 CTE returns 8 行和另一个 CTE (ABC) 为 7 行

我不知道为什么会成倍增加

EDIT2

; WITH CTE AS (
    SELECT EA.[EmailTypeID], EA.[EmailAddress], EA.[EntityID],
 row_number() over(partition by EA.EntityID order by EA.EntityID desc) as rn
    FROM [dbo].[Email_Addresses] EA
    JOIN [Entities] E ON E.[EntityID] = EA.[EntityID]
    JOIN (SELECT [MerchantOwnerID] FROM [dbo].[Merchant_Owners] WHERE [MerchantID] = 1) M ON M.[MerchantOwnerID] = E.[SourcePrimaryKey]
    JOIN (SELECT [EntityTypeID] FROM [Entity_Types] WHERE [EntityType] = 'MerchantOwner') ET ON ET.[EntityTypeID] = E.[EntityTypeID]
 ),
 ABC
 As
 (
 SELECT EB.[PhoneNumber], EB.[EntityID], EB.[PhoneType],
 row_number() over(partition by EB.EntityID order by EB.EntityID desc) as rn
    FROM [dbo].[Phones] EB
    JOIN [Entities] E ON E.[EntityID] = EB.[EntityID]
    JOIN (SELECT [MerchantOwnerID] FROM [dbo].[Merchant_Owners] WHERE [MerchantID] = 1) M ON M.[MerchantOwnerID] = E.[SourcePrimaryKey]
    JOIN (SELECT [EntityTypeID] FROM [Entity_Types] WHERE [EntityType] = 'MerchantOwner') ET ON ET.[EntityTypeID] = E.[EntityTypeID]
 ),
 GHK
 As
 (
  SELECT EB.[Address1], EB.[City], EB.[State],EB.[EntityID],
  row_number() over(partition by EB.EntityID order by EB.EntityID desc) as rn
    FROM [dbo].[Addresses] EB
    JOIN [Entities] E ON E.[EntityID] = EB.[EntityID]
    JOIN (SELECT [MerchantOwnerID] FROM [dbo].[Merchant_Owners] WHERE [MerchantID] = 1) M ON M.[MerchantOwnerID] = E.[SourcePrimaryKey]
    JOIN (SELECT [EntityTypeID] FROM [Entity_Types] WHERE [EntityType] = 'MerchantOwner') ET ON ET.[EntityTypeID] = E.[EntityTypeID]
 ),
 PQR
 As
 (
 SELECT EB.[MerchantOwnerID], EB.[FirstName], EB.[LastName],EB.[BusinessTitle],
 EB.[OwnershipPercentage], EB.[DateOfBirth],E.[EntityID],
  row_number() over(partition by E.EntityID order by E.EntityID desc) as rn
    FROM [dbo].[Merchant_Owners] EB
    JOIN [Entities] E ON E.[SourcePrimaryKey] = EB.[MerchantOwnerID] and [EntityTypeID]=2
    JOIN (SELECT [MerchantOwnerID] FROM [dbo].[Merchant_Owners] WHERE [MerchantID] = 1) M ON M.[MerchantOwnerID] = E.[SourcePrimaryKey]
    JOIN (SELECT [EntityTypeID] FROM [Entity_Types] WHERE [EntityType] = 'MerchantOwner') ET ON ET.[EntityTypeID] = E.[EntityTypeID]
 )

SELECT STUFF((SELECT '::::' + CONVERT(NVARCHAR, [EmailTypeID]) + '_' + [EmailAddress]
            FROM CTE
            WHERE [EntityID] = c.[EntityID]
            ORDER BY [EmailTypeID]
            FOR XML PATH ('')),1,4,'') [EmailAddress],
   c.[EntityID],
   STUFF((SELECT '::::' + CONVERT(NVARCHAR, [PhoneType]) + '_' + [PhoneNumber]
            FROM ABC
            WHERE [EntityID] = c2.[EntityID]
            ORDER BY [PhoneType]
            FOR XML PATH ('')),1,4,'') [PhoneNumber],
   c2.[EntityID] as pid,
  c3.[City],c3.[State],c3.[EntityID], c4.[FirstName]

FROM CTE c  FULL JOIN ABC c2 ON c.EntityID = c2.EntityID,
GHK c3, PQR c4
--FULL JOIN
--GHK c3 ON c.EntityID = c3.EntityID

  WHERE c.rn = 1 OR c2.rn = 1 or c3.rn=1or c4.rn=1
  group by  c.[EntityID],c2.[EntityID],c3.EntityID,c4.EntityID

它抛出错误 Column 'GHK.City' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

如果我删除此字段,它会在 GHK.State 处抛出错误,依此类推...

我的 CTE (GHK) 已经 return 7 行,所以我认为他们不需要聚合它。

知道如何出行。

我的 CTE(PQR) 也是 returning distict 行。我也遇到了同样的错误。

根据您期望的输出,其中一种可能有效。

如果您希望每个 EmailTypeID(例如 12:::13、12:::14、13:::14)都有单独的结果,那么以下方法会起作用。

DECLARE @MyTableVariable TABLE([EmailAddress] NVARCHAR(100),[EmailTypeID] INT, [EntityID] INT)
INSERT @MyTableVariable VALUES ('abc@abc.com',12,101)
,('pqr@pqr.com',13,101)
,('koi@koi.com',12,102)
,('poi@poi.com',13,102)
,('blah@blah.com',14,102)
SELECT CONVERT(NVARCHAR, T1.[EmailTypeID]) + '_' + T1.[EmailAddress] + '::::' + CONVERT(NVARCHAR, T2.[EmailTypeID]) + '_' + T2.[EmailAddress] [EmailAddress]
    , T1.[EntityID]
FROM @MyTableVariable T1
JOIN @MyTableVariable T2 ON T1.[EntityID] = T2.[EntityID] AND T2.[EmailTypeID] > T1.[EmailTypeID]

如果您只需要一个连接,那么这会起作用:

DECLARE @MyTableVariable2 TABLE([EmailAddress] NVARCHAR(100),[EmailTypeID] INT, [EntityID] INT)
INSERT @MyTableVariable2 VALUES ('abc@abc.com',12,101)
,('pqr@pqr.com',13,101)
,('koi@koi.com',12,102)
,('poi@poi.com',13,102)
,('blah@blah.com',14,102)
SELECT STUFF((SELECT '::::' + CONVERT(NVARCHAR, [EmailTypeID]) + '_' + [EmailAddress]
            FROM @MyTableVariable2
            WHERE [EntityID] = T1.[EntityID]
            ORDER BY [EmailTypeID]
            FOR XML PATH ('')),1,4,'') [EmailAddress]
    , [EntityID]
FROM @MyTableVariable2 T1
GROUP BY [EntityID]

附带说明一下,我认为您的查询作为一系列联接而不是一系列 IN 语句看起来更具可读性。例如

SELECT EA.[EmailTypeID], EA.[EmailAddress], EA.[EntityID]
FROM [dbo].[Email_Addresses] EA
JOIN [Entities] E ON E.[EntityID] = EA.[EntityID]
JOIN (SELECT [MechantOwnerID] FROM [dbo].[MechantOwners] WHERE [MechantID] = 1) M ON M.[MerchantOwnerID] = E.[SourcePrimaryKey]
JOIN (SELECT [EntityTypeID] FROM [Entity_Types] WHERE [EntityType] = 'MerchantOwner') ET ON ET.[EntityTypeID] = E.[EntityTypeID]

编辑(一起显示整个查询):

; WITH CTE AS (
    SELECT EA.[EmailTypeID], EA.[EmailAddress], EA.[EntityID]
    FROM [dbo].[Email_Addresses] EA
    JOIN [Entities] E ON E.[EntityID] = EA.[EntityID]
    JOIN (SELECT [MechantOwnerID] FROM [dbo].[MechantOwners] WHERE [MechantID] = 1) M ON M.[MerchantOwnerID] = E.[SourcePrimaryKey]
    JOIN (SELECT [EntityTypeID] FROM [Entity_Types] WHERE [EntityType] = 'MerchantOwner') ET ON ET.[EntityTypeID] = E.[EntityTypeID])
SELECT STUFF((SELECT '::::' + CONVERT(NVARCHAR, [EmailTypeID]) + '_' + [EmailAddress]
            FROM CTE
            WHERE [EntityID] = T1.[EntityID]
            ORDER BY [EmailTypeID]
            FOR XML PATH ('')),1,4,'') [EmailAddress]
    , [EntityID]
FROM CTE T1
GROUP BY [EntityID]

如果您更喜欢使用当前查询(或者如果我的查询由于某种原因不起作用),只需编辑 CTE 中的内容即可。

EDIT2(添加了 phone 数字内容):

; WITH CTE AS (
    SELECT EA.[EmailTypeID], EA.[EmailAddress], EA.[EntityID]
    FROM [dbo].[Email_Addresses] EA
    JOIN [Entities] E ON E.[EntityID] = EA.[EntityID]
    JOIN (SELECT [MerchantOwnerID] FROM [dbo].[Merchant_Owners] WHERE [MerchantID] = 1) M ON M.[MerchantOwnerID] = E.[SourcePrimaryKey]
    JOIN (SELECT [EntityTypeID] FROM [Entity_Types] WHERE [EntityType] = 'MerchantOwner') ET ON ET.[EntityTypeID] = E.[EntityTypeID]
),
ABC
As
(
    SELECT EB.[PhoneNumber], EB.[EntityID], EB.[PhoneType]
    FROM [dbo].[Phones] EB
    JOIN [Entities] E ON E.[EntityID] = EB.[EntityID]
    JOIN (SELECT [MerchantOwnerID] FROM [dbo].[Merchant_Owners] WHERE [MerchantID] = 1) M ON M.[MerchantOwnerID] = E.[SourcePrimaryKey]
    JOIN (SELECT [EntityTypeID] FROM [Entity_Types] WHERE [EntityType] = 'MerchantOwner') ET ON ET.[EntityTypeID] = E.[EntityTypeID]
)


SELECT STUFF((SELECT '::::' + CONVERT(NVARCHAR, [EmailTypeID]) + '_' + [EmailAddress]
        FROM CTE
        WHERE [EntityID] = T1.[EntityID]
        ORDER BY [EmailTypeID]
        FOR XML PATH ('')),1,4,'') [EmailAddress],
        T1.[EntityID],
        STUFF((SELECT '::::' + CONVERT(NVARCHAR, [PhoneType]) + '_' + [PhoneNumber]
        FROM ABC
        WHERE [EntityID] = T1.[EntityID]
        ORDER BY [PhoneType]
        FOR XML PATH ('')),1,4,'') [PhoneNumber]
FROM CTE T1
LEFT JOIN ABC T2 ON T2.[EntityID] = T1.[EntityID]
GROUP BY T1.[EntityID]

编辑 3:

SELECT COALESCE(c.[EntityID], c2.[EntityID], c3.[EntityID], c4.[EntityID]) [EntityID]
    , STUFF((SELECT '::::' + CONVERT(NVARCHAR, [EmailTypeID]) + '_' + [EmailAddress]
        FROM CTE
        WHERE [EntityID] = c.[EntityID]
        ORDER BY [EmailTypeID]
        FOR XML PATH ('')),1,4,'') [EmailAddress]
    , STUFF((SELECT '::::' + CONVERT(NVARCHAR, [PhoneType]) + '_' + [PhoneNumber]
        FROM ABC
        WHERE [EntityID] = c2.[EntityID]
        ORDER BY [PhoneType]
        FOR XML PATH ('')),1,4,'') [PhoneNumber]
    , c3.[City], c3.[State], c4.[FirstName]
FROM CTE c  
FULL JOIN ABC c2 ON c.EntityID = c2.EntityID
FULL JOIN (SELECT * FROM GHK WHERE RN = 1) c3 ON c3.[EntityID] = c.[EntityID] OR c3.[EntityID] = c2.[EntityID]
FULL JOIN (SELECT * FROM PQR WHERE RN = 1) c4 ON c4.[EntityID] = c.[EntityID] OR c4.[EntityID] = c2.[EntityID] OR c4.[EntityID] = c3.[EntityID]
GROUP BY c.[EntityID], c2.[EntityID], c3.[EntityID], c4.[EntityID], c3.[City], c3.[State], c4.[FirstName]

作为使用 UNION 如何处理当前查询的示例,这应该有效(并且避免需要 GROUP BY,因为每个 entityID 只生成一行)。 编辑 4:

; WITH CTE AS (
    SELECT EA.[EmailTypeID], EA.[EmailAddress], EA.[EntityID]
    FROM [dbo].[Email_Addresses] EA
    JOIN [Entities] E ON E.[EntityID] = EA.[EntityID]
    JOIN (SELECT [MerchantOwnerID] FROM [dbo].[Merchant_Owners] WHERE [MerchantID] = 1) M ON M.[MerchantOwnerID] = E.[SourcePrimaryKey]
    JOIN (SELECT [EntityTypeID] FROM [Entity_Types] WHERE [EntityType] = 'MerchantOwner') ET ON ET.[EntityTypeID] = E.[EntityTypeID]
    )
, ABC AS (
    SELECT EB.[PhoneNumber], EB.[EntityID], EB.[PhoneType]
    FROM [dbo].[Phones] EB
    JOIN [Entities] E ON E.[EntityID] = EB.[EntityID]
    JOIN (SELECT [MerchantOwnerID] FROM [dbo].[Merchant_Owners] WHERE [MerchantID] = 1) M ON M.[MerchantOwnerID] = E.[SourcePrimaryKey]
    JOIN (SELECT [EntityTypeID] FROM [Entity_Types] WHERE [EntityType] = 'MerchantOwner') ET ON ET.[EntityTypeID] = E.[EntityTypeID]
    )
, GHK AS (
    SELECT EB.[Address1], EB.[City], EB.[State],EB.[EntityID],
        ROW_NUMBER() OVER(PARTITION BY E.EntityID ORDER BY E.EntityID) AS RN
    FROM [dbo].[Addresses] EB
    JOIN [Entities] E ON E.[EntityID] = EB.[EntityID]
    JOIN (SELECT [MerchantOwnerID] FROM [dbo].[Merchant_Owners] WHERE [MerchantID] = 1) M ON M.[MerchantOwnerID] = E.[SourcePrimaryKey]
    JOIN (SELECT [EntityTypeID] FROM [Entity_Types] WHERE [EntityType] = 'MerchantOwner') ET ON ET.[EntityTypeID] = E.[EntityTypeID]
    )
, PQR AS (
    SELECT EB.[FirstName], E.[EntityID],
        -- EB.[MerchantOwnerID], EB.[LastName],EB.[BusinessTitle], EB.[OwnershipPercentage], EB.[DateOfBirth],
        ROW_NUMBER() OVER(PARTITION BY E.EntityID ORDER BY E.EntityID) AS RN
    FROM [dbo].[Merchant_Owners] EB
    JOIN [Entities] E ON E.[SourcePrimaryKey] = EB.[MerchantOwnerID] and [EntityTypeID]=2
    JOIN (SELECT [MerchantOwnerID] FROM [dbo].[Merchant_Owners] WHERE [MerchantID] = 1) M ON M.[MerchantOwnerID] = E.[SourcePrimaryKey]
    JOIN (SELECT [EntityTypeID] FROM [Entity_Types] WHERE [EntityType] = 'MerchantOwner') ET ON ET.[EntityTypeID] = E.[EntityTypeID]
    )
, EntityList AS (
    SELECT [EntityID] FROM CTE
    UNION
    SELECT [EntityID] FROM ABC
    UNION
    SELECT [EntityID] FROM GHK
    UNION
    SELECT [EntityID] FROM PQR
    )
SELECT EL.[EntityID]
    , STUFF((SELECT '::::' + CONVERT(NVARCHAR, [EmailTypeID]) + '_' + [EmailAddress]
            FROM CTE
            WHERE [EntityID] = EL.[EntityID]
            ORDER BY [EmailTypeID]
            FOR XML PATH ('')),1,4,'') [EmailAddress]
    , STUFF((SELECT '::::' + CONVERT(NVARCHAR, [PhoneType]) + '_' + [PhoneNumber]
            FROM ABC
            WHERE [EntityID] = EL.[EntityID]
            ORDER BY [PhoneType]
            FOR XML PATH ('')),1,4,'') [PhoneNumber]
    , c3.[City], c3.[State], c4.[FirstName]
FROM EntityList EL
LEFT JOIN CTE c1 ON c1.[EntityID] = EL.[EntityID]
LEFT JOIN ABC c2 ON c2.[EntityID] = EL.[EntityID]
LEFT JOIN (SELECT * FROM GHK WHERE RN = 1) c3 ON c3.[EntityID] = EL.[EntityID]
LEFT JOIN (SELECT * FROM PQR WHERE RN = 1) c4 ON c4.[EntityID] = EL.[EntityID]
ORDER BY EL.[EntityID]