使用 COUNT() 左连接的 SQL
Posted
技术标签:
【中文标题】使用 COUNT() 左连接的 SQL【英文标题】:SQL to LEFT JOIN with COUNT() 【发布时间】:2017-11-22 11:44:14 【问题描述】:我正在处理 SQL,但遇到以下错误:
窗口函数只能出现在 SELECT 或 ORDER BY 子句中
发生错误是因为我的代码中有COUNT()
。我知道这是一个讨厌的代码,但有点工作......
因此它尝试通过tblAmpReport.WEB_ID
与WEB_ID
加入tblAmpReport
表。 WEB_IB
是用下面这个讨厌的代码计算的。但是,COUNT()
似乎引起了问题。有谁知道克服这个问题的更好方法?
left join tblAmplianceReport
on ISNULL(tblWebIDLegacy.WebProductStyleID,
case
when count(tblCrystalBeauty.STOCK_ON_HAND) over(partition by tblCrystalBeauty.ITEM_PARENT) > 1
then case
when count(tblCrystalBeauty.STOCK_ON_HAND) over(partition by tblCrystalBeauty.ITEM_PARENT+'_'+cast(tblCrystalBeauty.RETAIL_PRICE as varchar(10))) = count(tblCrystalBeauty.STOCK_ON_HAND) over(partition by tblCrystalBeauty.ITEM_PARENT)
then tblCrystalBeauty.ITEM_PARENT+'_'+tblCrystalBeauty.ITEM
else case
when count(tblCrystalBeauty.STOCK_ON_HAND) over(partition by tblCrystalBeauty.ITEM_PARENT) > 4
then tblCrystalBeauty.ITEM_PARENT+'_'+tblCrystalBeauty.ITEM
else tblCrystalBeauty.ITEM_PARENT
end
end
else tblCrystalBeauty.ITEM_PARENT
end) = tblAmplianceReport.WEB_ID
完整的 SQL:
select tblCrystalBeauty.GROUP_NO
,tblCrystalBeauty.GROUP_NAME
,tblCrystalBeauty.DEPT_NAME
,tblCrystalBeauty.CLASS_NAME
,tblCrystalBeauty.BRAND
,tblCrystalBeauty.MAIN_SEASON
,tblCrystalBeauty.SUB_SEASON
,tblCrystalBeauty.SUB_NAME
,tblCrystalBeauty.PRODUCT_TYPE
,tblCrystalBeauty.PL_CYCLE
,tblCrystalBeauty.ITEM as ITEM
,cast(tblCrystalBeauty.ITEM as int) as ITEM_VALUE
,tblCrystalBeauty.ITEM_DESC
,tblCrystalBeauty.ITEM_PARENT as ITEM_PARENT
,cast(tblCrystalBeauty.ITEM_PARENT as int) as ITEM_PARENT_VALUE
,tblCrystalBeauty.***
,tblCrystalBeauty.SUPP_COLOUR
,tblCrystalBeauty._COLOUR
,tblCrystalBeauty.SIZE_1
,tblCrystalBeauty.SIZE_2
,tblCrystalBeauty.RETAIL_PRICE
,tblCrystalBeauty.EAN as EAN
,cast(tblCrystalBeauty.EAN as bigint) as EAN_VALUE
,tblCrystalBeauty.WH_SOH
,tblCrystalBeauty.STOCK_ON_HAND
,tblCrystalBeauty.CREATE_DATETIME
,ISNULL(tblWebIDLegacy.WebProductStyleID,
case
when count(tblCrystalBeauty.STOCK_ON_HAND) over(partition by tblCrystalBeauty.ITEM_PARENT) > 1
then case
when count(tblCrystalBeauty.STOCK_ON_HAND) over(partition by tblCrystalBeauty.ITEM_PARENT+'_'+cast(tblCrystalBeauty.RETAIL_PRICE as varchar(10))) = count(tblCrystalBeauty.STOCK_ON_HAND) over(partition by tblCrystalBeauty.ITEM_PARENT)
then tblCrystalBeauty.ITEM_PARENT+'_'+tblCrystalBeauty.ITEM
else case
when count(tblCrystalBeauty.STOCK_ON_HAND) over(partition by tblCrystalBeauty.ITEM_PARENT) > 4
then tblCrystalBeauty.ITEM_PARENT+'_'+tblCrystalBeauty.ITEM
else tblCrystalBeauty.ITEM_PARENT
end
end
else tblCrystalBeauty.ITEM_PARENT
end) as "WEB_ID"
,case
when row_number() over(partition by ISNULL(ISNULL(tblODIPublished.WEB_PROD_STYLE_ID,tblWebIDLegacy.WebProductStyleID),tblCrystalBeauty.ITEM_PARENT) order by
(
select 1
)) > 1
then 0
else 1
end as OPTION_COUNT
,case
when sum(tblCrystalBeauty.STOCK_ON_HAND) over(partition by tblCrystalBeauty.ITEM_PARENT) > 0
then 'YES'
else 'NO'
end as IN_STOCK
,sum(tblCrystalBeauty.STOCK_ON_HAND) over(partition by tblCrystalBeauty.ITEM_PARENT) as STYLE_SOH
,case
when case
when tblCrystalBeauty.PL_CYCLE = 'Discontinued'
or tblCrystalBeauty.PL_CYCLE = 'Discontinued'
then 'NO'
else 'YES'
end = 'YES'
and case
when charindex('Dum',tblCrystalBeauty.CLASS_NAME) > 0
then 'NO'
else 'YES'
end = 'YES'
and tblBrands.WEB_ALLOWED = 'Yes'
then 1
else 0
end as CONGRUENCY
,ISNULL(tblBrands.CUTOUTS,'DN') as USE_COUTOUTS
,'' as MARKED_FOR_WEB_WEB_ID
,case
when tblMarkedForWeb.CREATE_DATETIME is not null
then 'YES'
else 'NO'
end as MARKED_FOR_WEB_SKU
,cast(tblMarkedForWeb.CREATE_DATETIME as datetime) as MFWD
,case
when tblODIPublished.SKU_B4N_UPLOAD_MODIFIED_DATE is not null
then 'YES'
else 'NO'
end as PUBLISHED
,cast(tblODIPublished.SKU_B4N_UPLOAD_MODIFIED_DATE as datetime) as PD
,case
when tblODIPublished.SKU_B4N_UPLOAD_MODIFIED_DATE is not null
then 1
else 0
end as PUBLISHED_COUNT
,case
when case
when tblBeautyCopy.COPY_COMPLETE_DATE is not null
then 'YES'
else 'NO'
end = 'YES'
and case
when tblAmplianceReport.IMAGE_DATE_UPLOADED is not null
then 'YES'
else 'NO'
end = 'YES'
and case
when tblODIPublished.SKU_B4N_UPLOAD_MODIFIED_DATE is not null
then 'YES'
else 'NO'
end = 'NO'
then 'YES'
else 'NO'
end as READY_TO_UPLOAD
,case
when tblAmplianceReport.IMAGE_DATE_UPLOADED is not null
then 'YES'
else 'NO'
end as IMG_UPLOADED
,tblAmplianceReport.IMAGE_DATE_UPLOADED as IUD
,tblBeautyCopy.COPY_COMPLETE_DATE
,case
when tblBeautyCopy.COPY_COMPLETE_DATE is not null
then 'YES'
else 'NO'
end as COPY_COMP
,tblBeautyCopy.COPY_COMPLETE_DATE as CACD
,case
when tblBeautyCopy.COPY_COMPLETE_DATE is not null
then 'YES'
else 'NO'
end as CAT_COMP
,case
when tblTransfers.CREATE_DATE is not null
then 'YES'
else 'NO'
end as TRANSFERRED_TO_PACKSHOT
,tblTransfers.CREATE_DATE as TTPD
,case
when tblImageOrder.DATE is not null
then 'YES'
else 'NO'
end as IMAGE_ORDER
,tblImageOrder.DATE as IOD
,MV_REP_PUBLISHED_WCID_LEVEL.ONLINE_FLAG as DW_ONLINE_FLAG_WCID
,MV_REP_PUBLISHED_WCID_LEVEL.PUBLISHED as DW_PUBLISHED_FLAG_WCID
,MV_REP_PUBLISHED_SKU_LEVEL.ONLINE_FLAG as DW_ONLINE_FLAG_SKU
,MV_REP_PUBLISHED_SKU_LEVEL.PUBLISHED as DW_PUBLISHED_FLAG_SKU
,ISNULL(tblDepartment.DEPARTMENT,'DN') as DEPARTMENT
from tblCrystalBeauty
left join tblODIPublished
on tblCrystalBeauty.ITEM = tblODIPublished.SKU
left join tblWebIDLegacy
on tblCrystalBeauty.ITEM = tblWebIDLegacy.SkuId
left join tblAmplianceReport
on ISNULL(tblWebIDLegacy.WebProductStyleID,
case
when count(tblCrystalBeauty.STOCK_ON_HAND) over(partition by tblCrystalBeauty.ITEM_PARENT) > 1
then case
when count(tblCrystalBeauty.STOCK_ON_HAND) over(partition by tblCrystalBeauty.ITEM_PARENT+'_'+cast(tblCrystalBeauty.RETAIL_PRICE as varchar(10))) = count(tblCrystalBeauty.STOCK_ON_HAND) over(partition by tblCrystalBeauty.ITEM_PARENT)
then tblCrystalBeauty.ITEM_PARENT+'_'+tblCrystalBeauty.ITEM
else case
when count(tblCrystalBeauty.STOCK_ON_HAND) over(partition by tblCrystalBeauty.ITEM_PARENT) > 4
then tblCrystalBeauty.ITEM_PARENT+'_'+tblCrystalBeauty.ITEM
else tblCrystalBeauty.ITEM_PARENT
end
end
else tblCrystalBeauty.ITEM_PARENT
end) = tblAmplianceReport.WEB_ID
left join tblBeautyCopy
on tblCrystalBeauty.ITEM_PARENT = tblBeautyCopy.RETEK_PARENT
left join tblMarkedForWeb
on tblCrystalBeauty.ITEM = tblMarkedForWeb.ITEM
left join tblImageOrder
on tblCrystalBeauty.ITEM_PARENT = tblImageOrder.ITEM_PARENT
left join tblBrands
on cast(tblCrystalBeauty.GROUP_NO as varchar(10))+'_'+tblCrystalBeauty.BRAND = tblBrands.PRIMARY_KEY
left join MV_REP_PUBLISHED_SKU_LEVEL
on tblCrystalBeauty.ITEM = MV_REP_PUBLISHED_SKU_LEVEL.SKU
left join MV_REP_PUBLISHED_WCID_LEVEL
on ISNULL(ISNULL(tblODIPublished.WEB_PROD_STYLE_ID,tblWebIDLegacy.WebProductStyleID),
case
when charindex('Oxfo',tblCrystalBeauty.SIZE_1) = 1
then cast(tblCrystalBeauty.ITEM_PARENT as varchar(10))+'OX'
else tblCrystalBeauty.ITEM_PARENT
end) = MV_REP_PUBLISHED_WCID_LEVEL.PRODUCT_ID
left join tblTransfers
on tblCrystalBeauty.ITEM = tblTransfers.ITEM
left join tblDepartment
on cast(tblCrystalBeauty.GROUP_NO as varchar(10))+'_'+tblCrystalBeauty.GROUP_NAME = tblDepartment.GROUP_NAME
where tblCrystalBeauty.ITEM_PARENT is not null
and tblCrystalBeauty.PL_CYCLE != 'Discontinued'
order by WEB_ID desc;
【问题讨论】:
请包括您的整个格式化查询,以及示例输入和输出。mysql
和sql-server
有什么关系?
HI @TimBiegeleisen,这是一个从 10 个表中返回 54 列的大型查询。代码如下:
在我看来,问题不在于计数,而在于计数之后的 OVER。这就是这里的窗口函数。您可能想尝试分离为子查询甚至 CTE。
Windowed functions can only appear in the SELECT or ORDER BY clauses的可能重复
【参考方案1】:
我相信您可以通过使用 APPLY 运算符来解决这个问题。在这里,您可以参考您的其他表,只需将您的“加入”部分移动到 where 子句。
在您的情况下,它应该类似于:
cross apply (
select ISNULL(tblWebIDLegacy.WebProductStyleID,
case
when count(tblCrystalBeauty.STOCK_ON_HAND) over(partition by tblCrystalBeauty.ITEM_PARENT) > 1
then case
when count(tblCrystalBeauty.STOCK_ON_HAND) over(partition by tblCrystalBeauty.ITEM_PARENT+'_'+cast(tblCrystalBeauty.RETAIL_PRICE as varchar(10))) = count(tblCrystalBeauty.STOCK_ON_HAND) over(partition by tblCrystalBeauty.ITEM_PARENT)
then tblCrystalBeauty.ITEM_PARENT+'_'+tblCrystalBeauty.ITEM
else case
when count(tblCrystalBeauty.STOCK_ON_HAND) over(partition by tblCrystalBeauty.ITEM_PARENT) > 4
then tblCrystalBeauty.ITEM_PARENT+'_'+tblCrystalBeauty.ITEM
else tblCrystalBeauty.ITEM_PARENT
end
end
else tblCrystalBeauty.ITEM_PARENT
end) as joincolumn
--Add columns you need at the main select
from tblAmplianceReport)
-- add this to your where clause at the end
where joincolumn = tblAmplianceReport.WEB_ID
【讨论】:
以上是关于使用 COUNT() 左连接的 SQL的主要内容,如果未能解决你的问题,请参考以下文章