使用 DISTINCT 值连接表的 SQL

Posted

技术标签:

【中文标题】使用 DISTINCT 值连接表的 SQL【英文标题】:SQL to join the table with DISTINCT values 【发布时间】:2018-01-13 13:17:00 【问题描述】:

我正在尝试通过 Excel 中的 ODBC 连接左连接两个表,但随后连接它返回多个值,因为表 tblMapSizes 不包含唯一值。尝试添加 DISTINCT 但抛出错误“子查询返回超过 1 个值”

LEFT JOIN tblMapSizes size ON c.SIZE_1 = (select DISTINCT(SUPPLIER_SIZES) from tblMapSizes)

tblMapSizes 包含列:ID、SUPPLIER_SIZES、SIZES。

如果有人知道解决方案,请帮助...

干杯!

这里有完整的代码:

SELECT

c.GROUP_NO,
c.GROUP_NAME,
c.DEPT_NAME,
c.CLASS_NAME,
ISNULL(c.BRAND, c.CLASS_NAME) as BRAND,
c.MAIN_SEASON,
c.SUB_SEASON,
c.SUB_NAME,
ISNULL(c.PRODUCT_TYPE, c.SUB_NAME) as PRODUCT_TYPE,
ISNULL(c.PL_CYCLE, 'New/Continuity') as PL_CYCLE,
c.ITEM,
CAST(c.ITEM as int) as ITEM_VALUE,
c.ITEM_DESC,
c.ITEM_PARENT,
CAST(c.ITEM_PARENT as int) as ITEM_PARENT_VALUE,
c.***,
c.SUPP_COLOUR,
c.ARNOTTS_COLOUR,
c.SIZE_1,
size.SIZES as SIZE_WEB,
c.SIZE_2,
c.RETAIL_PRICE,
c.EAN,
CAST(c.EAN as bigint) as EAN_VALUE,
c.WH_SOH,
c.STOCK_ON_HAND,


ISNULL(ISNULL(odi.WEB_PROD_STYLE_ID,l.WebProductStyleID),CASE WHEN CHARINDEX('Oxfo', c.SIZE_1) = 1 THEN CAST(c.ITEM_PARENT AS VARCHAR(10)) + 'OX' ELSE c.ITEM_PARENT END) as "WEB_ID",
case when row_number() over (partition by ISNULL(ISNULL(odi.WEB_PROD_STYLE_ID,l.WebProductStyleID),c.ITEM_PARENT) order by (select 1)) > 1 then 0 else 1 end as OPTION_COUNT,
CASE WHEN SUM(c.STOCK_ON_HAND) OVER (PARTITION BY c.ITEM_PARENT) > 0 THEN 'YES' ELSE 'NO' END as IN_STOCK,
SUM(c.STOCK_ON_HAND) OVER (PARTITION BY c.ITEM_PARENT) as STYLE_SOH,
CASE WHEN c.PL_CYCLE = 'Discontinued' OR CHARINDEX('Dum', c.CLASS_NAME) > 0 OR b.WEB_ALLOWED = 'No' THEN 0 ELSE 1 END as CONGRUENCY,
ISNULL(b.CUTOUTS,'DN') as USE_COUTOUTS,
CASE WHEN c.ITEM_PARENT = CASE WHEN w.ITEM = c.ITEM THEN c.ITEM_PARENT ELSE NULL END THEN c.ITEM_PARENT ELSE NULL END as MARKED_FOR_WEB_WEB_ID,
CASE WHEN w.CREATE_DATETIME IS NOT NULL THEN 'YES' ELSE 'NO' END AS MARKED_FOR_WEB_SKU,
w.CREATE_DATETIME,
CASE WHEN odi.SKU_B4N_UPLOAD_MODIFIED_DATE IS NOT NULL THEN 'YES' ELSE 'NO' END AS PUBLISHED,

cast(odi.SKU_B4N_UPLOAD_MODIFIED_DATE as datetime) as PD,

CASE WHEN odi.SKU_B4N_UPLOAD_MODIFIED_DATE IS NOT NULL THEN 1 ELSE 0 END AS PUBLISHED_COUNT,
CASE WHEN odi.SKU_B4N_UPLOAD_MODIFIED_DATE IS NULL AND co.COPY_COMPLETE_DATE IS NOT NULL AND amp.IMAGE_DATE_UPLOADED IS NOT NULL THEN 'YES' ELSE 'NO' END AS READY_TO_UPLOAD,

CASE WHEN amp.IMAGE_DATE_UPLOADED IS NOT NULL THEN 'YES' ELSE 'NO' END AS IMG_UPLOADED,
amp.IMAGE_DATE_UPLOADED as IUD,
co.COPY_COMPLETE_DATE,
CASE WHEN co.COPY_COMPLETE_DATE IS NOT NULL THEN 'YES' ELSE 'NO' END AS COPY_COMP,
CASE WHEN tr."CREATE DATE" IS NOT NULL THEN 'YES' ELSE 'NO' END as TRANSFERRED_TO_PACKSHOT,
tr."CREATE DATE" as TTPD,
CASE WHEN io.DATE IS NOT NULL THEN 'YES' ELSE 'NO' END as IMAGE_ORDER,
io.DATE as IOD,

wcid.ONLINE_FLAG as DW_ONLINE_FLAG_WCID,
wcid.PUBLISHED as DW_PUBLISHED_FLAG_WCID,

REPLACE(ISNULL(ISNULL(odi.WEB_PROD_STYLE_ID,l.WebProductStyleID),CASE WHEN CHARINDEX('Oxfo', c.SIZE_1) = 1 THEN CAST(c.ITEM_PARENT AS VARCHAR(10)) + 'OX' ELSE c.ITEM_PARENT END),'_','') as REPLACED


FROM tblCrystal  c

LEFT JOIN tblODIPublishedCSV odi ON c.ITEM = odi.SKU
LEFT JOIN tblWebIDLegacy l ON c.ITEM = l.SkuId
LEFT JOIN tblMapSizes size ON c.SIZE_1 = (select DISTINCT(SUPPLIER_SIZES) from tblMapSizes)
LEFT JOIN tblBrands b on CAST(c.GROUP_NO AS VARCHAR(10)) + '_' + c.BRAND=b.PRIMARY_KEY
LEFT JOIN tblMarkedForWeb w on c.ITEM=w.ITEM
LEFT JOIN tblDWCopy co on ISNULL(ISNULL(odi.WEB_PROD_STYLE_ID,l.WebProductStyleID),CASE WHEN CHARINDEX('Oxfo', c.SIZE_1) = 1 THEN CAST(c.ITEM_PARENT AS VARCHAR(10)) + 'OX' ELSE c.ITEM_PARENT END) = co.WEB_ID
LEFT JOIN tblAmplianceReport amp on ISNULL(ISNULL(odi.WEB_PROD_STYLE_ID,l.WebProductStyleID),CASE WHEN CHARINDEX('Oxfo', c.SIZE_1) = 1 THEN CAST(c.ITEM_PARENT AS VARCHAR(10)) + 'OX' ELSE c.ITEM_PARENT END) = amp.WEB_ID
LEFT JOIN tblTransfers tr on c.ITEM=tr.SKU
LEFT JOIN tblImageOrder io on c.ITEM_PARENT=io.ITEM_PARENT

LEFT JOIN MV_REP_PUBLISHED_WCID_LEVEL wcid on REPLACE(ISNULL(ISNULL(odi.WEB_PROD_STYLE_ID,l.WebProductStyleID),CASE WHEN CHARINDEX('Oxfo', c.SIZE_1) = 1 THEN CAST(c.ITEM_PARENT AS VARCHAR(10)) + 'OX' ELSE c.ITEM_PARENT END),'_','') = wcid.PRODUCT_ID

WHERE c.ITEM_PARENT IS NOT NULL

ORDER BY WEB_ID DESC

【问题讨论】:

您发布的查询看起来已损坏,并且不会以我见过的任何 SQL 风格运行。这是您的实际查询吗? 对不起,实际查询有 78 行,但正在工作的行如下所示: LEFT JOIN tblMapSizes size ON c.SIZE_1 = size.SUPPLIER_SIZES 但是,它返回多行,我只想要它返回一行 您需要在这里向我们展示一些数据。没有这个,恐怕没人能帮上忙。 @TimBiegeleisen 刚刚将完整代码添加到我的评论中 【参考方案1】:

在我的脑海里,你能不能尝试使用WHERE IN 而不是严格相等,即使用这个:

LEFT JOIN tblMapSizes size
    ON c.SIZE_1 IN (SELECT DISTINCT(SUPPLIER_SIZES) FROM tblMapSizes)

这应该会消除该特定错误。至于逻辑上是否正确,那就另当别论了。您需要进一步解释联接背后的逻辑。

【讨论】:

查询正在运行但空间不足,所以我想需要一些资源较少的东西......

以上是关于使用 DISTINCT 值连接表的 SQL的主要内容,如果未能解决你的问题,请参考以下文章

oracle用rowid去掉重复值

distinct的使用

Oracle-18-select语句初步&SQL中用算术表达式&别名的使用&连接运算符%distinct&where子句

解析mysql中:单表distinct多表group by查询去除重复记录

为每个不同的名称值连接不同的姓氏值

MySQL GROUP_CONCAT 返回重复值。无法使用 DISTINCT