我是SQL的新手,所以请不要犹豫,添加有关查询的其他评论。
我努力工作的数据库已经过时了,几乎完全没有限制。
这是我正在处理的查询:
select cp.id, cp.connectedId, pd.Name, prt.Data, pd.language, prt.FileName, pr.resourceType
from
[AAES_PAM_DEV].[dbo].[ConnectedProduct] cp
left join [AAES_PAM_DEV].[dbo].[Product] p
on cp.connectedId = p.id
left join [AAES_PAM_DEV].[dbo].[ProductResource] pr
on cp.connectedId = pr.id and cp.Company = pr.Company
inner join [AAES_PAM_DEV].[dbo].[ProductDescription] pd
on cp.connectedId = pd.id and cp.Company = pd.Company
left join [AAES_PAM_DEV].[dbo].[ProductResourceThumbnail] prt
on cp.connectedId = prt.ProductId and cp.Company = prt.CompanyName and pr.fileName = prt.FileName
where pd.language = 'en' order by cp.id
我现在要做的是根据resourceType(右边的列)选择行
我只想根据id,connectedId和language选择一个唯一的行。 我还希望它通过查看是否存在类型为&#34的资源类型来选择此行;我"首先,如果没有,那么选择资源类型是什么" S"如果这些都不存在,那么只需要找到它找到的第一行。
这是我想要的一个例子:
正如您所看到的,它是组合键(id,connectedId和language)上的唯一行,并且它只选择resourcetypeid =" I"中的一行。 因此,即使存在许多具有相同组合键的其他行,我也希望它选择一行,其中首先是resourcetypeid =" I"如果那不存在那么我希望它采取resourcetypeid =" S"如果不存在,它可以使用组合键(id,connectedId和language)找到它找到的第一行
我的尝试:
SELECT cp.id, cp.connectedId, pd.language, pr.resourceType
FROM (
SELECT cp.id, cp.connectedId, pd.language, pr.resourceType
, DENSE_RANK() OVER(ORDER BY [Priority]) AS [RANK]
FROM (
SELECT cp.id, cp.connectedId, pd.language, pr.resourceType
, CASE pr.resourceType
WHEN 'I' THEN 1
WHEN 'S' THEN 2
ELSE 3
END AS [Priority]
FROM [AAES_PAM_DEV].[dbo].[ConnectedProduct] cp
left join [AAES_PAM_DEV].[dbo].[Product] p
on cp.connectedId = p.id
left join [AAES_PAM_DEV].[dbo].[ProductResource] pr
on cp.connectedId = pr.id and cp.Company = pr.Company
inner join [AAES_PAM_DEV].[dbo].[ProductDescription] pd
on cp.connectedId = pd.id and cp.Company = pd.Company
left join [AAES_PAM_DEV].[dbo].[ProductResourceThumbnail] prt
on cp.connectedId = prt.ProductId and cp.Company = prt.CompanyName and pr.fileName = prt.FileName
WHERE pd.language = 'en'
GROUP BY cp.id, cp.connectedId, pd.language, pr.resourceType
) AS PrioritizedSelect
) AS RankedSelect
WHERE [RANK] = 1
这是我得到的错误:
Msg 4104,Level 16,State 1,Line 53 多部分标识符" cp.id"无法受约束。 Msg 4104,Level 16,State 1,Line 53 多部分标识符" cp.connectedId"无法受约束。 Msg 4104,Level 16,State 1,Line 53 多部分标识符" pd.language"无法受约束。 Msg 4104,Level 16,State 1,Line 53 多部分标识符" pr.resourceType"无法受约束。 消息4104,第16级,状态1,第51行 多部分标识符" cp.id"无法受约束。 消息4104,第16级,状态1,第51行 多部分标识符" cp.connectedId"无法受约束。 消息4104,第16级,状态1,第51行 多部分标识符" pd.language"无法受约束。 消息4104,第16级,状态1,第51行 多部分标识符" pr.resourceType"无法受约束。
答案 0 :(得分:1)
让我们从表格和联接开始。
product
外部加入connectedproduct
。 connectedproduct
中没有匹配记录时,product
中的记录如何存在?这应该是内部联接,或者表名称具有误导性。productresource
和productdescription
上加入外联接表id
和内联接表company
。因此,当他们id
正确关联时,公司怎么会出现不匹配? id
表格主键,对吧?那么,为什么唯一标识的记录会与connectedproduct
相关联,但会有另一个company
?这看起来很可疑。你是想在这里防范数据不一致吗?cp.id
为空。表中的记录怎么没有ID?表具有 ID,然后每个记录都有一个用于标识或的ID,它根本没有ID列。可空的ID在数据库中没有任何意义。然后你只想要"最好的"记录每cp.id
,cp.connectedId
和pd.language
。所以你想对你的记录进行排名。您可以使用分析函数ROW_NUMBER
来执行此操作,您可以按质量对记录进行排序,并为每组值#1提供最佳记录。之后,您可以将这些结果过滤为仅保留#1记录。
select id, connectedid, name, data, language, filename, resourcetype
from
(
select
cp.id,
cp.connectedid,
pd.name,
prt.data,
pd.language,
prt.filename,
pr.resourcetype,
row_number()
over(partition by cp.id, cp.connectedId, pd.language
order by case pr.resourcetype when 'I' then 1 when 'S' then 2 else 3 end) as rn
from aaes_pam_dev.dbo.connectedproduct cp
left join aaes_pam_dev.dbo.product p
on cp.connectedid = p.id
left join aaes_pam_dev.dbo.productresource pr
on cp.connectedid = pr.id
and cp.company = pr.company
inner join aaes_pam_dev.dbo.productdescription pd
on cp.connectedid = pd.id
and cp.company = pd.company
left join aaes_pam_dev.dbo.productresourcethumbnail prt
on cp.connectedid = prt.productid
and cp.company = prt.companyname
and pr.filename = prt.filename
where pd.language = 'en'
) ranked
where rn = 1
order by id;
答案 1 :(得分:0)
基本上,您可以使用该结构构建您的请求:
SELECT Id, ConnectedId, Language, RessourceType
FROM (
SELECT Id, ConnectedId, Language, RessourceType
, DENSE_RANK() OVER(ORDER BY [Priority]) AS [RANK]
FROM (
SELECT Id, ConnectedId, Language, RessourceType
, CASE RessourceType
WHEN 'I' THEN 1
WHEN 'S' THEN 2
ELSE 3
END AS [Priority]
FROM [ ... ]
WHERE [ ... ]
GROUP BY Id, ConnectedId, Language, RessourceType
) AS PrioritizedSelect
) AS RankedSelect
WHERE [RANK] = 1