I couldn't figure out how to optimize this query and I didn't find a similar query as example.
我无法弄清楚如何优化此查询,我没有找到类似的查询作为示例。
What would be the best way to rewrite this query in order not to have so many sub-queries in the select clause achieving the same result grouped by month/brand_id?
重写此查询的最佳方法是什么,以便在select子句中没有这么多子查询来实现按月/ brand_id分组的相同结果?
The DBMS is SQL Server.
DBMS是SQL Server。
select
o.brand_id,
count(o.item_id) as "Total bought items",
count(o.sell_date) as "Total sold items",
/* Amount of sold items grouped by month per item */
(select count(obj.sell_date) from tab_object as obj where month(obj.install_date) = 1 and obj.brand_id = b.brand_id) as "Jan",
(select count(obj.sell_date) from tab_object as obj where month(obj.install_date) = 2 and obj.brand_id = b.brand_id) as "Feb",
(select count(obj.sell_date) from tab_object as obj where month(obj.install_date) = 3 and obj.brand_id = b.brand_id) as "Mar",
(select count(obj.sell_date) from tab_object as obj where month(obj.install_date) = 4 and obj.brand_id = b.brand_id) as "Apr",
(select count(obj.sell_date) from tab_object as obj where month(obj.install_date) = 5 and obj.brand_id = b.brand_id) as "May",
(select count(obj.sell_date) from tab_object as obj where month(obj.install_date) = 6 and obj.brand_id = b.brand_id) as "Jun",
(select count(obj.sell_date) from tab_object as obj where month(obj.install_date) = 7 and obj.brand_id = b.brand_id) as "Jul",
(select count(obj.sell_date) from tab_object as obj where month(obj.install_date) = 8 and obj.brand_id = b.brand_id) as "Aug",
(select count(obj.sell_date) from tab_object as obj where month(obj.install_date) = 9 and obj.brand_id = b.brand_id) as "Sep",
(select count(obj.sell_date) from tab_object as obj where month(obj.install_date) = 10 and obj.brand_id = b.brand_id) as "Oct",
(select count(obj.sell_date) from tab_object as obj where month(obj.install_date) = 11 and obj.brand_id = b.brand_id) as "Nov",
(select count(obj.sell_date) from tab_object as obj where month(obj.install_date) = 12 and obj.brand_id = b.brand_id) as "Dec"
from tab_brand as b
left join tab_object as o on b.brand_id = o.brand_id
and year(o.sell_date) = 2012
where b.brand_id in (1234, 1324, 1423, 2314)
group by b.brand_id
order by b.brand_id;
2 个解决方案
#1
2
You're looking for a PIVOT
http://msdn.microsoft.com/en-us/library/ms177410(v=sql.105).aspx and join the results of that to a query to provide the totals
你正在寻找一个PIVOT http://msdn.microsoft.com/en-us/library/ms177410(v=sql.105).aspx并将其结果加入查询以提供总数
select TotalBought, TotalSold, months.* from
(
select
o.brand_id,
count(o.item_id) as TotalBought,
count(o.sell_date) as TotalSold
from tab_object o
where year(sell_date)=2012
group by brand_id
) totals
left join
(
select *
from (select brand_id, sell_date, left(datename(month,install_date),3) as InstallMonth
from tab_object where brand_id in (1234,1324,1423,2314) and year(sell_date)=2012
) src
pivot
( count(sell_date) for installmonth in ([Jan],[Feb],[Mar],[Apr],[May],[Jun],[Jul],[Aug],[Sep],[Oct],[Nov],[Dec])) p
) months
on totals.brand_id = months.brand_id
You don't seem to use the brand table either
您似乎也没有使用品牌表
#2
1
can you use
你能用吗?
select
o.brand_id,
count(o.item_id) as "Total bought items",
count(o.sell_date) as "Total sold items",
month(install_date) as mo_install,
count(sell_date) as count_sell_date
from tab_brand b
left join tab_object o on
b.brand_id = o.brand_id and year(o.sell_date) = 2012
where b.brand_id in (1234, 1324, 1423, 2314)
group by b.brand_id, month(install_date)
order by b.brand_id;
#1
2
You're looking for a PIVOT
http://msdn.microsoft.com/en-us/library/ms177410(v=sql.105).aspx and join the results of that to a query to provide the totals
你正在寻找一个PIVOT http://msdn.microsoft.com/en-us/library/ms177410(v=sql.105).aspx并将其结果加入查询以提供总数
select TotalBought, TotalSold, months.* from
(
select
o.brand_id,
count(o.item_id) as TotalBought,
count(o.sell_date) as TotalSold
from tab_object o
where year(sell_date)=2012
group by brand_id
) totals
left join
(
select *
from (select brand_id, sell_date, left(datename(month,install_date),3) as InstallMonth
from tab_object where brand_id in (1234,1324,1423,2314) and year(sell_date)=2012
) src
pivot
( count(sell_date) for installmonth in ([Jan],[Feb],[Mar],[Apr],[May],[Jun],[Jul],[Aug],[Sep],[Oct],[Nov],[Dec])) p
) months
on totals.brand_id = months.brand_id
You don't seem to use the brand table either
您似乎也没有使用品牌表
#2
1
can you use
你能用吗?
select
o.brand_id,
count(o.item_id) as "Total bought items",
count(o.sell_date) as "Total sold items",
month(install_date) as mo_install,
count(sell_date) as count_sell_date
from tab_brand b
left join tab_object o on
b.brand_id = o.brand_id and year(o.sell_date) = 2012
where b.brand_id in (1234, 1324, 1423, 2314)
group by b.brand_id, month(install_date)
order by b.brand_id;