年底不忙,还没放假。闲来无事玩数据库题。看到一道题,做完感觉很有收获。也加深了我对笛卡尔积的理解。现在记录在这里,题目是扣的,叫做“分数排名”,网上的一个大词:selects1.Score,count(distinct(s2.Score))asRankfromScoress1,Scoress2wheres1.Score<=s2.Scoregroupbys1.IdorderbyRank数据库表连接数据行匹配时会生成笛卡尔积。笛卡尔积的定义引用自百度百科:笛卡尔积是指数学中两个集合_X_和_Y_的笛卡尔积(Cartesianproduct)。也称为直积,表示为_X_×_Y_,第一个对象是_X_的成员,第二个对象是_Y_的所有可能有序对的成员之一[3]如果表在数据库中,连接将生成笛卡尔积临时表,本例如下:所有记录应为36行*4列查询第一条记录时:Id:1,Score3.50当限制wheres1.Score<=s2.Score时,结果集为:{(3.50,3.50),(3.50,3.65),(3.50,4.00),(3.50,3.85),(3.50,4.00),(3.50,3.65)}GROUPBYId为1,即SeparatingarecordexistsinId为1的数据集,如果不加GROUPBYId,则取所有结果集中最小的记录,不分组显示。最后用distinct去重s2分数留4,取count。即Rank为4{(3.50,3.50),(3.50,3.65),(3.50,4.00),(3.50,3.85)}第二条记录:Id:2,Score:3.65wheres1.Score<=s2.得分{(3.65,3.65),(3.65,4.00),(3.65,3.85),(3.65,4.00),(3.65,3.65)}{(3.65,3.65),(3.65,4.00),(3.65,3.85)),(3.65,3.85),(3.65,3.65)}GROUPBYId为2,分离出一条记录存在于Id为2的数据集中,然后去掉重复的s2分数留下3,即Rank为3{(3.65,3.65),(3.65,4.00)}{(3.65,3.85)}等等。最后,orderbyRank将数据按正序排序。如果去除Rank排序,得到如下结果集:[[3.50,4],[3.65,3],[4.00,1],[3.85,2],[4.00,1],[3.65,3]]]每条数据中的分数默认是按照表的Id排列的,证明上面分析的查询顺序是正确的
