两张表,projectType(ID,TypeName,FatherID),FatherID是父类ID,引用自projectType的ID,可为空。
数据如下...
1 体育项目 null,
2 全能体育项目 1,
3 艺术体育项目 1,
4 文艺项目 null
projectTable(ID,ProjectName,projectTypeID,InputeDate),其中,Inputedate是Datetime类型。
现在要得到的数据是这样的。。。
年份 体育项目 文艺项目
2007 8个 10个
2008 12个 2个
2009 12个 7个
注意:这里的体育项目里面所指的个数,是要包含全能体育项目和艺术体育项目 的。年份是从InputDate 里面取出来的。
难点有两个,第一个是如何计算出包括子类的project的个数,第二就是行转列。
尝试了很久,没有得到满意的结果...跪求高人指点.....
如果级数只有2级的话应该很简单了。就你的数据来说,大概就是 select count(1) from tb where id=1 or fatherId=1,这就是体育类的了,文艺类的一样。如果是不固定级数的,那么可以参考一下BOM树的方法,基本思路还是递归。
至于第一个问题,要么递归取子分类,然后获取所有的project个数。要么设计更好的数据库表结构,进行无递归获取,例如,设计projectType的结构如下:
projectType(ID, DisplayOrder, CategoryName, CreatedDate)
DisplayOrder为string,CreatedDate为datatime类型。DisplayOrder的取值为父分类的DisplayOrder加上当前分类的CreatedDate转换为String的值。这样就可以通过如下sql取某个分类下的所有数据:
CREATE PROCEDURE [dbo].[GetChildrenProjectTypes]
(
@Parent nvarchar(750)
)
AS
SELECT
ID,
DisplayOrder,
REPLICATE( ' ', ( ( LEN( DisplayOrder ) / 23 ) - 1 ) * 5 ) AS Indent,
CategoryName,
CreatedDate
FROM projectType
WHERE
LEFT(DisplayOrder, 23) = @Parent
AND
(LEN( DisplayOrder ) / 23 ) > 1
ORDER BY
DisplayOrder
使用这个存储过程稍加改造就可以达到效果了。
参考自asp.net portal 的数据库设计。
SQL SERVER 2008 测试成功,T-SQL如下:
SELECT YEAR(InputDate) AS 日期,SUM(体育项目) AS 体育项目,SUM(文艺项目) AS 文艺项目
FROM
(
SELECT ID ,
CASE TypeName
WHEN '体育项目' THEN '体育项目'
WHEN '全能体育项目' THEN '体育项目'
WHEN '文艺体育项目' THEN '体育项目'
WHEN '文艺项目' THEN '文艺项目'
END Type
FROM projectType
) AS a
INNER JOIN projectTable ON a.ID=projectTable.ProjectTypeID
PIVOT(
COUNT(projectTable.ID)
FOR Type IN(体育项目,文艺项目)
) AS c
GROUP BY YEAR(InputDate)