mysql经典查询

来源:互联网 发布:linux mongodb安装 编辑:程序博客网 时间:2024/05/17 15:58


需求:根据任务单编号分组打印四类单据单据

数据库表结构:

(1)四种单据分别在四个不同的表中

(2)每个表中都有一个任务单编号,表示该单据属于那个任务单或哪个任务


第一种方式(此种方式有诸多弊端,而且当表增加时会导致繁琐不堪,不过里面仍有一些知识点,如果您的项目中急需此类问题的解决方案,可直接看第二种


查询之前的分析:

(1)如果要分组,可以考虑把这四类表放在一个视图中进行

*** 如何把它们放在同一个视图中呢?

只需要使用连接即可

*** 如何保证连接的时候所有需要的结果都被放到视图中

使用全连接,但是Mysql没有全连接,那就需要使用替代方法 full join =left join+union+right union,即先进性左联接,然后进行右连接,再把连接结果合并

***如何保证全连接后所有表的数据都不在同一行

on后的条件采用主键=主键的形式,而且此主键是UUID形式的(即保证连接条件永远不可能相同)

***四张表的全连接有许多的重复部分,这就会导致修改一处还要修改其它地方,而且其它地方还不止一处,如何减少修改量呢?

使用两两连接的方式,比如四张表abcd,先ab全连接得到e、cd全连接得到f,然后ef全连接,这样做的好处是修改时只需要修改ef的左联接即可,然后把左联接全部复制到把ef的左联接改成右连接即可




(2)如果要分组,可以考虑把它们的任务单编号放在视图中的某一列,然后对此列进行分组

*** 如何把四种表的任务单列放在试图中的同一列?

使用CONCAT即可,准确的说是利用concat和union在一起时的特性来让实现这个目的

这个特性是 当union的时候,union会把类似CONCAT(wltt) alltt1这样形式同名列合并成一列


弊端:

(1)如果表太多,则会导致写法相当繁琐,即使写出来也是难以维护的,极不推荐

(2)其实有了第一点已经没有必要再提这点了,但是就是想仍不住写这一点,即如果有个表中没有查到数据则会导致结果排序列结果不正确。

下面是sql代码,建议不要看,看了头疼可别说我没有提醒。

SELECT u1.*,u2.*,CONCAT(alltt1) alltt3  FROM (SELECT *  ,CONCAT(wltt) alltt1 FROM (SELECT wl.id wlid,wl.no wlno,wl.time,wl.truckWeight,wl.totalWeight,wl.goodsWeight,wl.taskTableId wltt,wl.workPoint wlwp,wl.vin,gt.name,gt.no gtno,d.no dno,d.name dname,gm.no gmno,gm.name gmname FROM weigninglist wl,goodsType gt,driver d,goodsMaster gmWHERE wl.goodsTypeId = gt.goodsTypeId AND wl.driverId=d.driverId AND wl.goodsMasterId = gm.goodsMasterId)  AS wl2LEFT JOIN (SELECT  id sid ,s.no sno,location,payType,payAmount,statementTime,taskTableId stt,workPoint swp FROM statement s  ) AS s2ON wlid=sid  UNION   <span style="font-family: Arial, Helvetica, sans-serif;">------此处即图中的ab全连接</span>SELECT *  ,CONCAT(stt) alltt1 FROM (SELECT wl.id wlid,wl.no wlno,wl.time,wl.truckWeight,wl.totalWeight,wl.goodsWeight,wl.taskTableId wltt,wl.workPoint wlwp,wl.vin,gt.name,gt.no gtno,d.no dno,d.name dname,gm.no gmno,gm.name gmname FROM weigninglist wl,goodsType gt,driver d,goodsMaster gmWHERE wl.goodsTypeId = gt.goodsTypeId AND wl.driverId=d.driverId AND wl.goodsMasterId = gm.goodsMasterId)  AS wl2RIGHT JOIN (SELECT  id sid ,s.no sno,location,payType,payAmount,statementTime,taskTableId stt,workPoint swp FROM statement s  ) AS s2ON wlid=sid  )u1LEFT JOIN(SELECT * ,CONCAT(ttt) alltt FROM (SELECT t.id tid,t.no tno,t.who,t.way ,t.reason ,t.time ttime,t.taskTableId ttt,t.workPoint twp,d.name dname,d.no dno FROM trafficTicket t,driver d WHERE t.driverId = d.driverId) AS t2LEFT JOIN (SELECT w.id wid,w.no wno,d.no wdno,d.name wdname ,c.name cname ,w.time wtime,w.taskTableId wtt,w.workPoint wwp,w.guardian FROM workbill w,company c,driver d WHERE w.driverId = d.driverId AND d.companyId = c.companyId) AS w2ON wid=tidUNION  <span style="font-family: Arial, Helvetica, sans-serif;">------此处即图中的cd全连接</span>SELECT * ,CONCAT(wtt) alltt FROM (SELECT t.id tid,t.no tno,t.who,t.way ,t.reason ,t.time ttime,t.taskTableId ttt,t.workPoint twp,d.name dname,d.no dno FROM trafficTicket t,driver d WHERE t.driverId = d.driverId) AS t2RIGHT JOIN (SELECT w.id wid,w.no wno,d.no wdno,d.name wdname ,c.name cname ,w.time wtime,w.taskTableId wtt,w.workPoint wwp,w.guardian FROM workbill w,company c,driver d WHERE w.driverId = d.driverId AND d.companyId = c.companyId) AS w2ON wid=tid)u2 ON wlid = wid  UNION  ------此处即图中的ef全连接SELECT u1.*,u2.* ,CONCAT(alltt) alltt3 FROM (SELECT *  ,CONCAT(wltt) alltt1 FROM (SELECT wl.id wlid,wl.no wlno,wl.time,wl.truckWeight,wl.totalWeight,wl.goodsWeight,wl.taskTableId wltt,wl.workPoint wlwp,wl.vin,gt.name,gt.no gtno,d.no dno,d.name dname,gm.no gmno,gm.name gmname FROM weigninglist wl,goodsType gt,driver d,goodsMaster gmWHERE wl.goodsTypeId = gt.goodsTypeId AND wl.driverId=d.driverId AND wl.goodsMasterId = gm.goodsMasterId)  AS wl2LEFT JOIN (SELECT  id sid ,s.no sno,location,payType,payAmount,statementTime,taskTableId stt,workPoint swp FROM statement s  ) AS s2ON wlid=sid  UNIONSELECT *  ,CONCAT(stt) alltt1 FROM (SELECT wl.id wlid,wl.no wlno,wl.time,wl.truckWeight,wl.totalWeight,wl.goodsWeight,wl.taskTableId wltt,wl.workPoint wlwp,wl.vin,gt.name,gt.no gtno,d.no dno,d.name dname,gm.no gmno,gm.name gmname FROM weigninglist wl,goodsType gt,driver d,goodsMaster gmWHERE wl.goodsTypeId = gt.goodsTypeId AND wl.driverId=d.driverId AND wl.goodsMasterId = gm.goodsMasterId)  AS wl2RIGHT JOIN (SELECT  id sid ,s.no sno,location,payType,payAmount,statementTime,taskTableId stt,workPoint swp FROM statement s  ) AS s2ON wlid=sid  )u1RIGHT JOIN(SELECT * ,CONCAT(ttt) alltt FROM (SELECT t.id tid,t.no tno,t.who,t.way ,t.reason ,t.time ttime,t.taskTableId ttt,t.workPoint twp,d.name dname,d.no dno FROM trafficTicket t,driver d WHERE t.driverId = d.driverId) AS t2LEFT JOIN (SELECT w.id wid,w.no wno,d.no wdno,d.name wdname ,c.name cname ,w.time wtime,w.taskTableId wtt,w.workPoint wwp,w.guardian FROM workbill w,company c,driver d WHERE w.driverId = d.driverId AND d.companyId = c.companyId) AS w2ON wid=tidUNIONSELECT * ,CONCAT(wtt) alltt FROM (SELECT t.id tid,t.no tno,t.who,t.way ,t.reason ,t.time ttime,t.taskTableId ttt,t.workPoint twp,d.name dname,d.no dno FROM trafficTicket t,driver d WHERE t.driverId = d.driverId) AS t2RIGHT JOIN (SELECT w.id wid,w.no wno,d.no wdno,d.name wdname ,c.name cname ,w.time wtime,w.taskTableId wtt,w.workPoint wwp,w.guardian FROM workbill w,company c,driver d WHERE w.driverId = d.driverId AND d.companyId = c.companyId) AS w2ON wid=tid)u2 ON wlid = wid    ORDER BY alltt3


第二种方式

完全使用union

技术要点:

(1)保证所有表的查询列的个数要相同,对于有些列比较少的表可使用类似 "id  cx"这样的无关列补齐,保证和列最多的表一致即可

(2)如果要区分是哪种表,可在每个表的查询结果中加一列 如在a表中加一列“   ‘wl’ c0   ”这样在名为c0的列显示的都是wl,表示这是a表

(3)把所有表任务单号放到同一列,我放在了c0列

</pre><pre name="code" class="sql">SELECT * FROM (
---a表SELECT  taskTableId c0,'wl' c1,wl.id c2,wl.no c3,wl.time c4,wl.truckWeight c5,wl.totalWeight c6,wl.goodsWeight c7,wl.workPoint c8,wl.vin c9,         gt.name c10,gt.no c11,d.no c12,d.name c13,gm.no c14,gm.name c15FROM weigninglist wl,goodsType gt,driver d,goodsMaster gmWHERE wl.goodsTypeId = gt.goodsTypeId AND wl.driverId=d.driverId AND wl.goodsMasterId = gm.goodsMasterIdUNION---b表SELECT  taskTableId c0,'s' c1,id c2 ,s.no c3,statementTime c4,payType c5,payAmount c6,location c7,workPoint c8 ,id c9,id c10,id c11,id c12,id c13,id c14,id c15  FROM statement s  WHERE 1=1UNION---c表SELECT taskTableId c0,'t' c1,t.id c2,t.no c3,t.time c4,t.way c5,t.reason c6,t.who c7,t.workPoint c8,d.name c9,d.no c10,id c11,id c12,id c13,id c14,id c15FROM trafficTicket t,driver d WHERE t.driverId = d.driverIdUNION---d表SELECT taskTableId c0,'w' c1,w.id c2,w.no c3,d.no c4,d.name c5 ,co.name c6 ,w.time c7,w.workPoint c8,w.guardian c9 ,d.no c10,id c11,id c12,id c13,id c14,id c15FROM workbill w,company co,driver d WHERE w.driverId = d.driverId AND d.companyId = co.companyId) AS c ORDER BY c0---通过排序实现分组


1 0
原创粉丝点击