我有一个SQL查询,希望你能帮我解决。
这应该很容易,我的头脑今天不生产。
以下是表格的示例
TblProducts
ID | SKU | Price
-----------------
1 | ABC | 10.00
2 | DEF | 5.00
3 | OSKD | 6.00
4 | 123 | 6.00
5 | LPD | 12.00
6 | TRE | 3.00
TblCategories
ID | Name | Active |Sort
-------------------------
1 | Home | 1 |4
2 | Garden| 1 |55
3 | Misc | 1 |2
4 | Test | 0 |1
TblAlternateCategoryName
ID | CategoryID | AltName
-------------------------
1 | 1 | House
2 | 1 | Crib
3 | 3 | Anything
TblProductXCategories
ID | ProductID | CategoryID | SortOrder
---------------------------------------
1 | 1 | 1 | 1
2 | 1 | 2 | 1
4 | 2 | 2 | 4
5 | 2 | 3 | 6
6 | 3 | 3 | 6
7 | 4 | 4 | 0
8 | 5 | 2 | 1
需要此结果
SKU | Price | Category | AlternateCategory
-------------------------------------------
ABC | 10.00 | Home | House
DEF | 5.00 | Misc | Anything
OSKD | 6.00 | Misc | Anything
LPD | 12.00 | Garden | Null
规则
提前致谢
这是原始的SQL Statment
DECLARE @feedID int =4
SELECT Pro_Chl.id,
Pro_Chl.sku,
Pro_Chl.productname,
(SELECT top 1 tbl_componentsettinglist.componentsubtype
FROM tbl_offers
INNER JOIN tbl_componentsettinglist
ON tbl_offers.id = tbl_componentsettinglist.componentid
WHERE ( tbl_componentsettinglist.componentsubtype = N'Free Shipping' )
AND ( tbl_componentsettinglist.componenttype = N'Offer' )
AND ( tbl_offers.startdate <= { fn NOW() } )
AND ( tbl_offers.enddate > { fn NOW() } )
AND ( tbl_offers.enabled = 1 )
AND ( Pro_Chl.id = tbl_componentsettinglist.setting1 )
ORDER BY tbl_offers.[order]) AS FreeShipping,
TblCategories.name AS CategoryName,
TblAlternateCategoryName.value AS FeedCat
FROM TblProducts AS Pro_Chl
INNER JOIN (
SELECT productid,
categoryid,
sortorder
FROM TblProductXCategories main
WHERE sortorder = (
SELECT top 1 Min(srt.sortorder)
FROM TblProductXCategories srt
INNER JOIN TblCategories
ON srt.categoryid =
TblCategories.id
WHERE srt.productid = main.productid
AND srt.categoryid = main.categoryid
AND TblCategories.hidden = 0
)
)
AS PxC
ON ( Pro_Chl.id = PxC.productid
OR Pro_Chl.parentid = PxC.productid )
INNER JOIN TblCategories
ON PxC.categoryid = TblCategories.id
LEFT OUTER JOIN TblAlternateCategoryName
ON PxC.categoryid = TblAlternateCategoryName.categoryid AND TblAlternateCategoryName.feedid = @feedID
WHERE (
( Pro_Chl.parentid = '' )
AND ( Pro_Chl.id NOT IN (SELECT parentid
FROM TblProducts AS pc
WHERE ( customproperties LIKE '%upc%' )) )
AND ( Pro_Chl.status = 1 )
AND ( Pro_Chl.manufacturerid IS NOT NULL )
AND ( Pro_Chl.manufacturerid <> '' )
AND ( Pro_Chl.manufacturerid <> '- No Manufacturer -' )
AND ( Pro_Chl.id NOT IN (SELECT productid
FROM TblProductschoicecombinations
WHERE available = 0) )
AND Pro_Chl.manufacturerid NOT IN (
'f46c9a25-8172-49a8-991a-a8219663453b' )
)
OR
(
( Pro_Chl.parentid <> '' )
AND ( Pro_Chl.customproperties LIKE '%upc%' )
AND ( Pro_Chl.parentid IN (SELECT id
FROM TblProducts AS cp
WHERE ( status = 1 )
AND ( parentid = '' )) )
AND ( Pro_Chl.status = 1 )
AND ( Pro_Chl.manufacturerid IS NOT NULL )
AND ( Pro_Chl.manufacturerid <> '' )
AND ( Pro_Chl.manufacturerid <> '- No Manufacturer -' )
AND ( Pro_Chl.id NOT IN (SELECT productid
FROM TblProductschoicecombinations
WHERE available = 0) )
AND Pro_Chl.manufacturerid NOT IN (
'f46c9a25-8172-49a8-991a-a8219663453b'
)
)
答案 0 :(得分:2)
这是SQLFiddle demo。此查询选择带有min的类别(TblCategory.Sort)。如果您需要选择min类别(TblProductXCategories.SortOrder),只需将OVER语句中的 order by 列替换为TBlProductXCategories.SortOrder。它可以与重复的排序器一起使用
with t as
(select TblProductXCategories.*,TblCategories.Name CatName,
row_number() over (partition by ProductID order by TblCategories.Sort) rownum
from TblProductXCategories
join TblCategories on TblProductXCategories.CategoryId = TblCategories.id
and TblCategories.Active=1
)
select TblProducts.SKU,TblProducts.Price,t.CatName,
(select top 1 AltName from TblAlternateCategoryName
where TblAlternateCategoryName.CategoryId=t.CategoryId order by Id )
from t
left join TblProducts on t.productid=TblProducts.id
where rownum=1
或没有WITH的等价物。 SQLFiddle:
select TblProducts.SKU,TblProducts.Price,t.CatName,
(select top 1 AltName
from TblAlternateCategoryName
where TblAlternateCategoryName.CategoryId=t.CategoryId
order by Id ) AltCat
from
(select TblProductXCategories.*,
TblCategories.Name CatName,
row_number()
over (partition by ProductID order by TblCategories.Sort) rownum
from TblProductXCategories
join TblCategories on TblProductXCategories.CategoryId = TblCategories.id
and TblCategories.Active=1
) t
left join TblProducts on t.productid=TblProducts.id
where rownum=1
答案 1 :(得分:1)
根据您的示例数据,您将获得Alternate Category
的两个结果,因为Home
类别有两个备用项,因此最终结果为5行而不是您要求的两行。但是下面的查询应该为您提供所需的结果:
select x1.sku, x1.price, c.name, ac.altname
from
(
select x.sku, p.price, x.sort
from
(
select p.sku, min(c.sort) sort
from products p
left join ProductXCategories pxc
on p.id = pxc.productid
left join Categories c
on pxc.categoryid = c.id
group by p.sku
) x
inner join products p
on x.sku = p.sku
) x1
inner join categories c
on x1.sort = c.sort
left join AlternateCategoryName ac
on c.id = ac.categoryid
where c.active = 1
编辑:如果您希望将备用类别合并为一列:
select distinct x1.sku,
x1.price,
c.name,
STUFF((SELECT ',' + ac.altname
FROM AlternateCategoryName ac
WHERE
c.id = ac.categoryid
FOR XML PATH('')
),1,1,'') altname
from
(
select x.sku,
p.price,
x.sort
from
(
select p.sku,
min(c.sort) sort
from products p
left join ProductXCategories pxc
on p.id = pxc.productid
left join Categories c
on pxc.categoryid = c.id
group by p.sku
) x
inner join products p
on x.sku = p.sku
) x1
inner join categories c
on x1.sort = c.sort
left join AlternateCategoryName ac
on c.id = ac.categoryid
where c.active = 1
编辑#2:您声明只需要一个备用分类。您需要确定所需的alt名称的条件,但以下内容将选择max(altname)
:
select x1.sku,
x1.price,
c.name,
ac.altname
from
(
select x.sku,
p.price,
x.sort
from
(
select p.sku,
min(c.sort) sort
from products p
left join ProductXCategories pxc
on p.id = pxc.productid
left join Categories c
on pxc.categoryid = c.id
group by p.sku
) x
inner join products p
on x.sku = p.sku
) x1
left join categories c
on x1.sort = c.sort
left join
(
select categoryid, max(altname) altname
from AlternateCategoryName
group by categoryid
) ac
on c.id = ac.categoryid
where c.active = 1
答案 2 :(得分:0)
以下查询忽略了替代类别(您说它不是必需的)。并且,它假定类别中的排序值没有重复:
select SKU, price, c.name
from (select P.SKU, p.price,
MIN(p.sort) as minsort
from tblProducts p join
tblProductXCategories pxc
on p.id = pxc.productid join
tblCategory c
on pxc.categoryid = c.categoryid and
active = 1
group by P.SKU, p.price
) p join
tblCategories c
on p.minsort = c.sort
它将所有内容连接在一起,计算minsort,然后加入类别信息。
如果您在排序中有重复项,则可以通过以下方式选择其中一个来解决问题:
select SKU, price, c.name
from (select P.SKU, p.price,
MIN(p.sort) as minsort
from tblProducts p join
tblProductXCategories pxc
on p.id = pxc.productid join
tblCategory c
on pxc.categoryid = c.categoryid and
active = 1
group by P.SKU, p.price
) p join
(select c.*,
row_number() over (partition by sort order by newid()) as seqnum
from tblCategories c
) c
on p.minsort = c.sort and
c.seqnum = 1
这会输入一个随机序列号,然后选择第一个序列号。当有关系时,应该从选项中做出相同的选择。