如何在包含其他几个查询的 sql 查询中对表进行连接?

Posted

技术标签:

【中文标题】如何在包含其他几个查询的 sql 查询中对表进行连接?【英文标题】:How to make a join on a table in an sql query that contains several others? 【发布时间】:2021-11-08 13:00:50 【问题描述】:

我是 SQL 的初学者,我有一个 sql 查询,它返回我需要的表信息,表 ARTICLE_MODE

GA_CODEARTICLE C1 C2 C3 GA_LIBELLE C5 C6 GA_LIBREART3 GA_LIBREART5
BUTSS5-RC SURF HARD WARE - Wetsuits DAY COVER 2021 UNISEXE SURF SOF

我需要检索有关第二个表的列的信息。 表MTMPTVGEN 的列MZS_DPAETAST

在这两个表中,两列包含一些相同的信息:

ARTICLE_MODE 表中的 GA_CODEARTICLE 列。

MTMPTVGEN的列MZS_ARTICLE

GA_CODEARTICLE MZS_ARTICLE
BUTSS5-RC BUTSS5-RC
BUTS85-RC BUTS85-RC
BUTS75-RC VMA045-VC

我尝试执行此查询来检索列 MZS_DPAETAST 的值,这些值具有公共值 GA_CODEARTICLEMZS_ARTICLE,它返回给我很多结果:

select MZS_DPAETAST from MTMPTVGEN LEFT OUTER JOIN ARTICLE_MODE on MZS_ARTICLE=GA_CODEARTICLE

但是如何在我的初始查询中插入它?感谢您的帮助。

SELECT GA_CODEARTICLE, CC1.CC_LIBELLE AS C1, 
YX2.YX_LIBELLE AS C2, 
YX3.YX_LIBELLE AS C3, 
GA_LIBELLE, 
CC4.CC_LIBELLE AS C5, 
CC5.CC_LIBELLE AS C6,
CC6.CC_LIBELLE AS C15,
GA_LIBREART3,
GA_LIBREART5
FROM ARTICLE_MODE  
LEFT OUTER JOIN PGI_LOOKUP(GCFAMILLENIV1) CC1 ON GA_FAMILLENIV1=CC1.CC_CODE 
AND CC1.CC_TYPE="FN1"   
LEFT OUTER JOIN PGI_LOOKUP(GCLIBREART1) YX2 ON GA_LIBREART1=YX2.YX_CODE 
AND YX2.YX_TYPE="LA1"   
LEFT OUTER JOIN PGI_LOOKUP(GCLIBREART2) YX3 ON GA_LIBREART2=YX3.YX_CODE 
AND YX3.YX_TYPE="LA2"   
LEFT OUTER JOIN PGI_LOOKUP(GCCOLLECTION) CC4 ON GA_COLLECTION=CC4.CC_CODE 
AND CC4.CC_TYPE="GCO"  
LEFT OUTER JOIN PGI_LOOKUP(GCFAMILLENIV2) CC5 ON GA_FAMILLENIV2=CC5.CC_CODE 
AND CC5.CC_TYPE="FN2"
LEFT OUTER JOIN PGI_LOOKUP(GCFAMILLENIV5) CC6 ON GA2_FAMILLENIV5=CC6.CC_CODE 
AND CC6.CC_TYPE="FN5"  
WHERE (GA_EMBALLAGE<>"X" 
AND (GA_TYPEARTICLE NOT IN ("PRE","FI","FRA","UL","PAC"))
AND ((GA_STATUTART="GEN")))  
ORDER BY GA_DATEMODIF DESC

【问题讨论】:

顺便问一下,您使用的是什么 DBMS?您应该始终使用相关 DBMS 标记 SQL 请求,因为 SQL 方言可能有很大差异,因此有时正确答案可能在很大程度上取决于 DBMS。 【参考方案1】:

很难理解您遇到的问题。您正在展示您知道如何加入article_modemtmptvgen。您有一个包含article_mode 的查询。那么是什么阻止你加入 mtmptvgen 呢?

您的查询有许多外连接。我不知道这些是否真的有必要。我现在也不喜欢mtmptvgen。我正在展示一个外部连接,但是如果这当然足够了,您可以将其设为内部连接。

SELECT 
  am.ga_codearticle, 
  cc1.cc_libelle as c1, 
  yx2.yx_libelle as c2, 
  yx3.yx_libelle as c3, 
  am.ga_libelle, 
  cc4.cc_libelle as c5, 
  cc5.cc_libelle as c6,
  cc6.cc_libelle as c15,
  am.ga_libreart3,
  am.ga_libreart5,
  m.mzs_dpaetast
FROM article_mode am
LEFT OUTER JOIN pgi_lookup(gcfamilleniv1) cc1 ON am.ga_familleniv1  = cc1.cc_code AND cc1.cc_type = 'FN1'   
LEFT OUTER JOIN pgi_lookup(gclibreart1)   yx2 ON am.ga_libreart1    = yx2.yx_code AND yx2.yx_type = 'LA1'   
LEFT OUTER JOIN pgi_lookup(gclibreart2)   yx3 ON am.ga_libreart2    = yx3.yx_code AND yx3.yx_type = 'LA2'   
LEFT OUTER JOIN pgi_lookup(gccollection)  cc4 ON am.ga_collection   = cc4.cc_code AND cc4.cc_type = 'GCO'  
LEFT OUTER JOIN pgi_lookup(gcfamilleniv2) cc5 ON am.ga_familleniv2  = cc5.cc_code AND cc5.cc_type = 'FN2'
LEFT OUTER JOIN pgi_lookup(gcfamilleniv5) cc6 ON am.ga2_familleniv5 = cc6.cc_code AND cc6.cc_type = 'FN5'  
LEFT OUTER JOIN mtmptvgen m ON m.mzs_article = am.ga_codearticle
WHERE am.ga_emballage <> 'X'
AND am.ga_typearticle NOT IN ('PRE', 'FI', 'FRA', 'UL', 'PAC')
AND am.ga_statutart = 'GEN'
ORDER BY am.ga_datemodif DESC;

(我添加了缺少的列限定符并用单引号替换了不合适的双引号。这些 应该是字符串文字,而不是列名,对吧?我也认为它会进行查询当所有内容都是大写并且在运算符、列名和文字之间没有空格时,很难阅读。)

更新

您说每个 article_mode 只有一个 mzs_dpaetast 值,但数据模型不合适,并将其冗余存储在每个相关的 mtmptvgen 行中。为了解决这个问题,您只需要为每个article_mode 行选择一个mtmptvgen 行。一种方法是加入查询而不是表:

LEFT OUTER JOIN
(
  SELECT mzs_article, MAX(mzs_dpaetast) AS mzs_dpaetast
  FROM mtmptvgen
  GROUP BY mzs_article
) m ON m.mzs_article = am.ga_codearticle

【讨论】:

感谢您对请求的回答和澄清,我现在明白了。我不知道我在查询中的加入是否可以同时拥有两个表中的值以及如何将其插入到其他表的中间。 啊,好吧。由于所有表都连接到article_mode,只有您可以按任何顺序放置连接;即连接的顺序无关紧要。您可以加入mtmptvgen 作为第一个或第二个,...或作为最后一个。没有区别。 好的,感谢您的澄清。而且这种查询语法可以应用于任何类型的数据库(mysql、SQL Server...)? 是的,这是标准 SQL,应该适用于每个 RDBMS。 (除了需要额外括号的 MS Access。) 很抱歉打扰您,但由于您修改了我的查询,我的列 'ga_codearticle' 有一些重复值,并且在我的表中,此列中不能有任何重复值。这是由于要更改联接吗?或者我们可以将查询修改为在此列中没有重复项?

以上是关于如何在包含其他几个查询的 sql 查询中对表进行连接?的主要内容,如果未能解决你的问题,请参考以下文章

如何在Sql中对表进行分组?

SQL中查询多个字段时,GROUP BY 要怎么使用?

如何在 SQL Redshift 中对表进行分区后比较两列的值

如何在 bigquery 中旋转我的 sql 表?

如何在 PDO 语句中对表名进行参数化? [复制]

使用嵌套行(类型 STRUCT)对表 SQL 进行重复数据删除