十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
先把分类全取出来,并随机排序,取排在第一个分类。
成都创新互联公司长期为成百上千家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为郎溪企业提供专业的成都网站设计、做网站,郎溪网站改版等技术服务。拥有10余年丰富建站经验和众多成功案例,为您定制开发。
例如:西装
然后查询的时候 order by (category='西装') desc,category 即可实现要求。
MySQL是一种开放源代码的关系型数据库管理系统(RDBMS),MySQL数据库系统使用最常用的数据库管理语言--结构化查询语言(SQL)进行数据库管理。
由于MySQL是开放源代码的,因此任何人都可以在General Public License的许可下下载并根据个性化的需要对其进行修改。MySQL因为其速度、可靠性和适应性而备受关注。大多数人都认为在不需要事务化处理的情况下,MySQL是管理内容最好的选择。
MySQL这个名字,起源不是很明确。一个比较有影响的说法是,基本指南和大量的库和工具带有前缀“my”已经有10年以上,而且不管怎样,MySQL AB创始人之一的Monty Widenius的女儿也叫My。这两个到底是哪一个给出了MySQL这个名字至今依然是个迷,包括开发者在内也不知道。
MySQL的海豚标志的名字叫“sakila”,它是由MySQL AB的创始人从用户在“海豚命名”的竞赛中建议的大量的名字表中选出的。获胜的名字是由来自非洲斯威士兰的开源软件开发者Ambrose Twebaze提供。根据Ambrose所说,Sakila来自一种叫SiSwati的斯威士兰方言,也是在Ambrose的家乡乌干达附近的坦桑尼亚的Arusha的一个小镇的名字。
MySQL,虽然功能未必很强大,但因为它的开源、广泛传播,导致很多人都了解到这个数据库。它的历史也富有传奇性。
前几天参加了一个公司的面试,到了后面面试官出了一个SQL相关的题目:
数据的形式类似于以下这样(表名为views):
当时为了稳妥起见,我的第一反应是使用窗口函数,
然后面试官问:“还有没有什么简便的方法么?”
很明显他的意思是要用传统的groupby来完成这个查询,确实我之前的查询又是用窗口函数又是加了distinct确实是复杂一些。
于是我用group by再写了一遍。
看完我的查询之后,面试官又问了一句:“可以不需要使用嵌套查询吗?”
当时我的回答是”应该不行,如果不使用嵌套而直接在group by后面加having的话sql会报错,就和where如果使用别名查询就会报错一样“
后面面试完想了一下,发现自己当时回答得不好,不是正确的但也不完全错,不是正确的原因是按照sql的规则having后面是可以拿聚合函数做判断的,但是不完全错的原因是如果having用的是像我之前设置的别名来判断的话,确实是会出错的。(虽然mysql在5.6之后基于sql的规则对group by进行拓展,支持这种写法。但在其它sql上面用别名having还是不行的)
我们可以从SQL运行时各部分的执行顺序来进行分析,当我们选择执行一个SQL语句的时候,它会按照以下的顺序来进行操作,
这个执行顺序的设计是很巧妙的,我说一下我自己对于上述顺序的理解,
1. FROM
顾名思义,当执行查询语句的时候,首先需要知道的是它需要哪些表,正如我们去一个地方需要知道它的具体位置一样。如果需要多个表的话在这一部分也需要按照一定的顺序进行表的join操作。
2. WHERE
当确定我们需要读取哪一张表(或者多张表)的数据之后,我们就需要进行where的filter操作,根据filter尽量减少读取的数据数量。
那么问题来了,为什么where的优先级要比group by,having, select之类的要高呢?
第一个原因是可以减少不必要的查询量,加快执行语句的速度,类似于Apache Spark在对查询语句进行逻辑优化时需要用到的谓词下推类似的道理。举个栗子,比如我们可能需要userid从100到300的用户对于某一个页面的浏览次数,那么如果先执行group by再执行where的话,userid小于100的用户的数据也会被汇总进去,但实际上这些部分的数据是完全不需要的,计算它们完全是浪费系统资源(而且group by操作本身就是很耗资源的操作)
3. GROUP BY
在完成where操作的过滤之后,如果语句中有group by的话则会对过滤后的数据进行聚合操作,聚合操作是多对一的转换,因此在聚合操作过后,除了用于group by的字段之外,其它字段的原始数据将会丢失,只能得到它们相应的聚合结果(比如sum(), avg()这样)
在完成聚合操作之后,参与group by的字段以及其它字段对应的聚合值已经处于已知状态,后续的操作可以直接使用它们。
4. HAVING
HAVING操作主要做的是对group by之后的分组结果进行过滤,可以根据参与group by的字段进行过滤,也可以根据其它字段的聚合值进行过滤。(因为聚合值在这里已经算是已知数据)因此这里是可以拿聚合函数做判断的,比如最开始的那个查询的例子,可以直接写成以下的形式,
HAVING并不是一定要和group by成对出现的,它也可以单独存在,在没有group by的时候,此时默认只有一个组,但是需要注意的是这时having里面参与过滤的字段需要在select里面存在,不然having会不知道这是分组里面的内容而导致报错。
5. SELECT
选取结果集中相对应的字段,在select中为字段设置的别名在此阶段及之后的操作中生效。
6. DISTINCT
去重操作,放在select之后有个原因是去重操作是要根据select里面所选字段来进行的。
7. ORDER BY
对得到的结果按照特定字段顺序进行排列,这里可以使用别名
8. LIMIT
设置显示结果集中的几条数据
通过分析MySQL中各部分的执行顺序,我们就不难理解为什么where不能有别名,而having可以用聚合函数来判断的原因,而且借此机会重新温习一遍SQL各部分对应的功能,加深理解,可以说是一举两得。
①From:对from左边的表和右边的表计算笛卡尔积,产生虚拟表c1()
②On:对c1中的数据进行on过滤,只有符合过滤条件的数据记录才会记录在虚拟表c2中
③Join:若指定了连接条件(left、right),主表中的未匹配的行就会作为外部行添加到c2中,生成虚拟表c3
④Where:对虚拟表c3中的数据进行条件过滤,符合过滤条件的记录插入到虚拟表c4中
⑤Group by:根据group by子句中的列,对c4中的记录进行分组操作,生成c5
⑥Having:对虚拟表c5中的记录进行having过滤,符合筛选条件的记录插入虚拟表c6中
⑦Select:执行select操作,选择指定的列,插入到虚拟表c7中
⑧Distinct:对c7中的数据去重,生成虚拟表c8
⑨Order by:对虚拟表c8中的数据按照指定的排序规则进行排序,生成虚拟表c9
⑩Limit:取出指定的记录,产生虚拟表c10,将结果返回
上面是我看他们博客都这样写的!但是我觉得不适合我理解。可能是我太菜,我就以我写的sql理解下执行过程。
1、首先是找到from字段和join字段后面的所有表,形成笛卡尔积。student、English、class形成笛卡尔积。
2、然后是哪种(inner、join、right)join并且根据on字段对笛卡尔积做改变(这个改变因on改变行的条数,因为join类型去重某些行和置空某些列)。
3、是根据where字段去再次筛选上步得到的笛卡尔积。
4、然后group by去分组。
5、之后select 列结构(列结构就此不变)
6、因为distinct只能对单个列字段去重,所以肯定的在select后再去执行(行结构就此不变)。
7、order by是排序,能排序就说明整个表的行的条数不会发生改变了。
8、limit字段是最后从上面结果选一部分出去。
执行顺序只是相对的,在mysql优化器语法分析器分析优化的时候会给我们优化,在保证语义不变的情况下,进行语义等价转换。所以上面的顺序只是一般情况下可以这样分析。