所以我有以下架构:
我正在尝试以下列格式获取数据:
________________________________________
| Id | Property1 | Property2 | Property3 |
_________________________________________
| 123| Value1 | Value2 | Value3 |
________________________________________
所以,我编写SQL查询的方式是这样的:
SELECT
Id
,(SELECT pv.Value FROM CampaignProperty AS cp LEFT JOIN PropertyValue AS pv ON cp.Id = pv.CampaignPropertyId WHERE cp.Name = "Property1" AND pv.ContactId = c.Id AND cp.CampaignId = c.ActiveCampaignId) AS "Property1"
,(SELECT pv.Value FROM CampaignProperty AS cp LEFT JOIN PropertyValue AS pv ON cp.Id = pv.CampaignPropertyId WHERE cp.Name = "Property2" AND pv.ContactId = c.Id AND cp.CampaignId = c.ActiveCampaignId) AS "Property2"
,(SELECT pv.Value FROM CampaignProperty AS cp LEFT JOIN PropertyValue AS pv ON cp.Id = pv.CampaignPropertyId WHERE cp.Name = "Property3" AND pv.ContactId = c.Id AND cp.CampaignId = c.ActiveCampaignId) AS "Property3"
FROM Contact c
我遇到的问题是我已经为10多个属性做了这个,我有几个LEFT JOIN和多个过滤器使我的查询难以置信地表现不佳。在SQL Management studio中对此进行分析后,我发现瓶颈在上面显示的SELECT中。
我如何获得相同的结果但性能更好?还有其他方法可以进行查询吗?
重要的是要注意PropertyValue
表目前还没有索引......
答案 0 :(得分:2)
由于多个级别的加入,这有点棘手。我想你想要:
SELECT cp.ContactId,
MAX(CASE WHEN cp.Name = 'Property1' THEN pv.CampaignProperty END) as Property1,
MAX(CASE WHEN cp.Name = 'Property2' THEN pv.CampaignProperty END) as Property2,
MAX(CASE WHEN cp.Name = 'Property3' THEN pv.CampaignProperty END) as Property3
FROM Contact c LEFT JOIN
CampaignProperty cp
ON cp.ContactId = c.id AND
cp.CampaignId = c.ActiveCampaignId LEFT JOIN
PropertyValue pv
ON cp.Id = pv.CampaignPropertyId
FROM Contact c
GROUP BY c.Id;
为了提高性能,您需要CampaignProperty(ContactId, CampaignId, Id, Name)
和PropertyValue(CampaignPropertyId, CampaignProperty)
上的索引。
答案 1 :(得分:0)
您可以通过单个SELECT
语句执行聚合:
select c.id, max(case when cp.Name = 'Property1' then cp.value end) as Property1,
max(case when cp.Name = 'Property2' then cp.value end) as Property2,
max(case when cp.Name = 'Property3' then cp.value end) as Property3
from Contact c left join
CampaignProperty cp
on c.id = cp.ContactId left join
PropertyValue pl
on pl.CampaignPropertyId = cp.id
group by c.id;
答案 2 :(得分:0)
如果你可以使用多行
SELECT c.ID, cp.Name, pv.Value
FROM Contact c
JOIN CampaignProperty AS cp
ON cp.CampaignId = c.ActiveCampaignId
AND cp.Name IN ('Property1', 'Property2', 'Property3')
LEFT JOIN PropertyValue AS pv
ON cp.Id = pv.CampaignPropertyId
AND pv.ContactId = c.Id
ORDER BY c.ID, cp1.Name