一个mysql查询问题

昨天写了个对于我来说很复杂的sql语句。 这里先放个图:

现在的需要的数据如图:从product表中拿到id,name两个字段,从buy_contract_Item和sale_contract_Item中拿到quantity,totalMoney这两个字段,再从buy_contract和sale_contract中拿到contract_date字段,同时以合同签定时间为查询条件将商品各类的数量和金额sum,最后返回获取结果。表与表的关联关系如图。

后来问了下同事,拿到了返回结果:

一开始就犯了个错误,虽然从 buy_contract_Item和sale_contract_Item获取的信息比较多,但却不能以他们为主表,这是昨天半天还没有结果的主要原因。因为所有后续的这些表都是以商品为主,为商品的买进和卖出服务的。所以这里以商品为主表做查询。

第一步:从product表中拿到Id,Name两个字段(其他的字段在后面扩充)

SELECT id,name FROM product

第二步:从buy_contract_item中拿到productId,SUM(quantity),SUM(totalMoney)这两个字

段并按组分类

--productId 为了后面与product表做关联条件的

SELECT  productId,SUM(quantity),SUM(totalMoney)

FROM  buy_contract_item

GROUP BY productId

第三步:从sale_contract_item中拿到SUM(quantity),SUM(totalMoney)这两个字段并按组

分类

SELECT

productId,SUM(quantity),SUM(totalMoney)

FROM  sale_contract_item

GROUP BY productId

第四步: 对第二步的SELECT语句进行扩充,联结buy_contract:

获取SUM(quantity),SUM(totalMoney)和contract_date

SELECT productId,SUM(quantity),SUM(totalMoney),contract_date

FROM  buy_contract_item  a

JOIN buy_contract b ON a.contract_id = b.id

GROUP BY a.product_id;

第五步:添加where查询条件,另外再加上别名

SELECT productId,SUM(quantity) AS buyQuantity,SUM(totalMoney) AS buyTotalMoney,b.contract_date

FROM  buy_contract_item  a

JOIN buy_contract b ON a.contract_id = b.id

WHERE 1=1  and (b.contract_date >= ‘2015-03-13‘  and b.contract_date <= ‘2015-03-15‘)

GROUP BY a.product_id;

第六步:写出sale的情况和上面类似

SELECT productId,SUM(quantity) AS saleQuantity,SUM(totalMoney) AS saleTotalMoney,d.contract_date

FROM  buy_contract_item  c

JOIN buy_contract d ON c.contract_id = d.id

WHERE 1=1  and (d.contract_date >= ‘2015-03-13‘  and d.contract_date <= ‘2015-03-15‘)

GROUP BY c.product_id;

第一步、第五步、第六步左联结

SELECT  t.id,t.name,

IFNULL(buyQuantity,0) AS buyQuantity,

IFNULL(buyTotalMoney,0) AS buyTotalMoney,

IFNULL(saleQuantity,0) AS saleQuantity,

IFNULL(saleTotalMoney,0) AS saleTotalMoney

FROM product t

LEFT JOIN

(

SELECT productId,SUM(quantity) AS buyQuantity,SUM(totalMoney) AS buyTotalMoney,b.contract_date

FROM  buy_contract_item  a

JOIN buy_contract b ON a.contract_id = b.id

WHERE 1=1  and (b.contract_date >= ‘2015-03-13‘  and b.contract_date <= ‘2015-03-15‘)

GROUP BY a.product_id;

) m ON t.id = m.productId

LEFT JOIN

(

SELECT productId,SUM(quantity) AS saleQuantity,SUM(totalMoney) AS saleTotalMoney,d.contract_date

FROM  buy_contract_item  c

JOIN buy_contract d ON c.contract_id = d.id

WHERE 1=1  and (d.contract_date >= ‘2015-03-13‘  and d.contract_date <= ‘2015-03-15‘)

GROUP BY c.product_id;

) n ON t.id = n.productId

ORDER BY buyQuantity DESC, saleQuantity DESC

写的中间可能还有错误,但大致思路是这样,复杂的sql语句,可以先写整体框架,然后在框架里不断的细化查询。

时间: 2024-10-20 10:07:45

一个mysql查询问题的相关文章

Mysql查询缓存碎片、缓存命中率及Nagios监控

Mysql 的优化方案,在互联网上可以查找到非常多资料,今天对Mysql缓存碎片和命中率作了详细了解,个人作了简单整理. 一.Mysql查询缓存碎片和缓存命中率. mysql> SHOW STATUS LIKE 'qcache%'; +-------------------------+-----------+ | Variable_name | Value | +-------------------------+-----------+ | Qcache_free_blocks | 5 |

MySQL查询计划输出列的含义

"一:MySQL查询计划输出列的含义:1.id:每个被独立执行的操作的标识,表示对象被操作的顺序:id值越大,先被执行:如果相同,执行顺序从上到下.2.select_type:查询中每个select子句的类型.3.table:名字,被操作的对象的名称,通常是表名,但有其他格式.4.partitions:匹配的分区信息(对于非分区表值为NULL).5.type:连接操作的类型.6.possible_keys:备选的索引(列出可能被使用到的索引).7.key:经优化器选定的索引:常使用ANALYZE

mysql查询缓存打开、设置、参数查询、性能变量意思

http://blog.sina.com.cn/s/blog_75ad10100101by7j.html http://www.cnblogs.com/zemliu/archive/2013/08/03/3234372.html 第一: query_cache_type 使用查询缓存的方式 一般,我们会把 query_cache_type 设置为 ON,默认情况下应该是ON mysql> select @@query_cache_type;+--------------------+| @@qu

Mysql查询语句使用select.. for update导致的数据库死锁分析

近期有一个业务需求,多台机器需要同时从Mysql一个表里查询数据并做后续业务逻辑,为了防止多台机器同时拿到一样的数据,每台机器需要在获取时锁住获取数据的数据段,保证多台机器不拿到相同的数据. 我们Mysql的存储引擎是innodb,支持行锁.解决同时拿数据的方法有很多,为了更加简单,不增加其他表和服务器的情况下,我们考虑采用select... for update的方式,这样X锁锁住查询的数据段,表里其他数据没有锁,其他业务逻辑还是可以操作. 这样一台服务器比如select .. for upd

MYSQL查询性能优化

查询的基础知识 MySQL查询过程如下图所示: MySQL是通过查询语句的哈希查找来命中缓存的,需要注意的是如果查询语句大小写不一致或者有多余的空格,是不会命中缓存的. 一个查询通常有很多执行方式,查询优化器通过计算开销(随机读取次数)来选择最优的查询. MySQL把所以的查询都当做联接来处理,联接是按照循环嵌套的策略来执行的,如下图所示: 查询的优化和限制 我们需要知道查询优化器会做哪些优化,这样在写查询的时候就可以不需要考虑手动来做这些优化,把这些事情交给查询优化器去做是更好的选择,查询优化

MySQL查询大小写是否敏感问题分析

mysql数据库在做查询时候,有时候是英文字母大小写敏感的,有时候又不是的,主要是由mysql的字符校验规则的设置决定的,通常默认是不支持的大小写字母敏感的.  1. 什么是字符集和校验规则? 字符集是一套符号和编码.校对规则是在字符集内用于比较字符的一套规则.任何一个给定的字符集至少有一个校对规则,它可能有几个校对规则.要想列出一个字符集的校对规则,使用SHOW COLLATION语句. 校对规则一般有这些特征: 两个不同的字符集不能有相同的校对规则. 每个字符集有一个默认校对规则.例如,ut

mysql查询语句

mysql查询语句常用SELECT命令打印当前的日期和时间select now();打印当前的日期select curdate();打印当前时间select curtime();查看当前版本select version();打印当前用户select user();查看当前数据库实例select database();查看系统中可用的变量show variables;查看系统中全局变量show global variables;一般查询系统可用变量或是全局变量都是通过like的方式来进行查询的,因

MySQL查询数据表中数据记录(包括多表查询)

MySQL查询数据表中数据记录(包括多表查询) MySQL查询数据表中数据记录(包括多表查询) 转自:http://www.baike369.com/content/?id=5355 在MySQL中创建数据库的目的是为了使用其中的数据. 使用select查询语句可以从数据库中把数据查询出来. select语句的语法格式如下: select selection_list // 要查询的内容,选择哪些列 from table_list // 从什么表中查询,从何处选择行 where primary_

MySQL查询缓存打开、设置、参数查询、性能变量

query_cache_type 使用查询缓存的方式 一般,我们会把query_cache_type 设置为 ON,默认情况下应该是ON mysql> SELECT @@query_cache_type; +--------------------+ | @@query_cache_type | +--------------------+ | ON | +--------------------+ query_cache_type有3个值 0代表关闭查询缓存OFF,1代表开启ON,2(DEMA