左连接计数来自第二个表的三个属性

Posted

技术标签:

【中文标题】左连接计数来自第二个表的三个属性【英文标题】:Left join counts from second table on three attributes 【发布时间】:2020-06-27 22:10:02 【问题描述】:

注意:我在这个数据库中没有写权限。

我有一个事务表,我需要在其中计算事务数:DONE

SELECT
unique_id, 
journey_files_id, 
version_template_code, 
Count (*) as cnt

FROM [XXX].[dbo].[CampaignResponse]
WHERE version_template_code LIKE '%FPQ%'
AND CAST(email_action_date AS DATE) >='02/01/2020' and CAST(email_action_date AS DATE) <='02/29/2020'

GROUP BY unique_id, journey_files_id, version_template_code ORDER BY cnt DESC

现在我需要使用 unique_id、journey_files_id、version_template_code 将此视图加入到第二个表中

当前查询无效:

SELECT DISTINCT *
FROM [XXX].[dbo].[EmailSend] a

LEFT JOIN
(
SELECT 
    unique_id, 
    journey_files_id, 
    version_template_code, 
    Count (email_action) as cnt

FROM [XXX].[dbo].[CampaignResponse]
WHERE version_template_code LIKE '%FPQ%'
AND CAST(email_action_date AS DATE) >='02/01/2020' and CAST(email_action_date AS DATE) <='02/29/2020'


) b ON a.unique_id = b.unique_id 
    AND a.journey_files_id = b.journey_files_id
    AND a.version_template_code = b.version_template_code

WHERE CAST(a.processed AS DATE) >='02/01/2020' and CAST(a.processed AS DATE) <='02/29/2020'
GROUP BY [id]
  ,a.[unique_id]
  ,a.[journey_files_id]
  ,a.[version_template_code]
  ,[ecrm_template_code]
  ,[lead_type]
  ,[quote_number]
  ,[email]
  ,[company_name]
  ,[sl_code]
  ,[kw_subject_line]
  ,[promo_line]
  ,[headline]
  ,[image_top]
  ,[learn_more]
  ,[tfn]
  ,[subhead_1]
  ,[body_copy_1]
  ,[subhead_2]
  ,[bullet_1]
  ,[offer]
  ,[video_img]
  ,[video_url]
  ,[video_copy]
  ,[legal]
  ,[kw_url_01]
  ,[kw_url_02]
  ,[variable_01]
  ,[variable_02]
  ,[tracking_pixel_url]
  ,[processed]
  ,b.cnt
  ,b.unique_id, b.journey_files_id, b.version_template_code
   ORDER BY b.unique_id

错误信息:

消息 8120,第 16 级,状态 1,第 8 行 列“AJM.dbo.CampaignResponse.unique_id”在选择列表中无效,因为它不包含在聚合函数或 GROUP BY 子句中。

这是有道理的 - 我似乎无法想出解决办法。

非常感谢您的帮助。

【问题讨论】:

你为什么使用GROUP BYDISTINCT 您使用 * 通配符来选择所有列,但并非所有由此选择的列都在 group by 子句中命名。任何选择但不在 group by 子句中的列都必须应用显式聚合。由于这个原因,* 通配符和 group by 子句通常不会组合在一起。 【参考方案1】:

您不需要在内部查询之外使用group by,因为您没有在外部计算任何聚合值。您只需要一个简单的left join 如下:

SELECT DISTINCT *
FROM [XXX].[dbo].[EmailSend] a
left join (SELECT
unique_id, 
journey_files_id, 
version_template_code, 
Count (*) as cnt
FROM [XXX].[dbo].[CampaignResponse]
WHERE version_template_code LIKE '%FPQ%'
AND CAST(email_action_date AS DATE) >='02/01/2020' and CAST(email_action_date AS DATE) <='02/29/2020'
GROUP BY unique_id, journey_files_id, version_template_code) b
ON a.unique_id = b.unique_id AND a.journey_files_id = b.journey_files_id AND a.version_template_code = b.version_template_code 
ORDER BY cnt DESC

【讨论】:

Msg 1033,级别 15,状态 1,第 11 行 ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效,除非还包含 TOP、OFFSET 或 FOR XML指定的。完成时间:2020-03-16T14:42:01.5149991-05:00 我将order by 移到了内部查询之外。你能看看它现在是否有效吗?【参考方案2】:

仅在该表中进行分组(为安全起见,还编辑了日期和日期范围):

with b as 
(
SELECT
unique_id, 
journey_files_id, 
version_template_code, 
Count (*) as cnt

FROM [XXX].[dbo].[CampaignResponse]
WHERE version_template_code LIKE '%FPQ%'
AND CAST(email_action_date AS DATE) >='20200201' and CAST(email_action_date AS DATE) < '20200301'

GROUP BY unique_id, journey_files_id, version_template_code
)
SELECT DISTINCT *
FROM [XXX].[dbo].[EmailSend] a
LEFT JOIN
 b ON a.unique_id = b.unique_id 
    AND a.journey_files_id = b.journey_files_id
    AND a.version_template_code = b.version_template_code
WHERE CAST(a.processed AS DATE) >='20200201' and CAST(a.processed AS DATE) <'20200301'
   ORDER BY b.unique_id

编辑:如果您愿意,与子查询相同:

SELECT DISTINCT *
FROM [XXX].[dbo].[EmailSend] a
LEFT JOIN
(
SELECT
unique_id, 
journey_files_id, 
version_template_code, 
Count (*) as cnt

FROM [XXX].[dbo].[CampaignResponse]
WHERE version_template_code LIKE '%FPQ%'
AND CAST(email_action_date AS DATE) >='20200201' and CAST(email_action_date AS DATE) < '20200301'

GROUP BY unique_id, journey_files_id, version_template_code
)
 b ON a.unique_id = b.unique_id 
    AND a.journey_files_id = b.journey_files_id
    AND a.version_template_code = b.version_template_code
WHERE CAST(a.processed AS DATE) >='20200201' and CAST(a.processed AS DATE) <'20200301'
   ORDER BY b.unique_id;

【讨论】:

它不允许我在我的子查询中 GROUB BY,现在是否允许它,因为它现在包装在 CTE 中? @AmberWilliams,不,它也适用于子查询。我只是想让它更干净。在您的情况下,您试图在聚合函数位于子查询中时对结果进行分组。编辑以包括子查询版本。同理,CTE版本可读性更强。 我现在明白了!非常感谢。

以上是关于左连接计数来自第二个表的三个属性的主要内容,如果未能解决你的问题,请参考以下文章

如何编写两个表的正确左连接?

如何在 EF / EF Core 中的第二个表上实现具有某些条件的左连接?

左连接的 SQL 计数

在pyspark中加入2个表,多个条件,左连接?

Oracle_SQL 连接和子查询

EF Core 左连接计数