ID   Name Age City MajorID 101Tom 20BeiJing 10102Lucy 18ShangHai 11数据库联表查询及重复记录字段合并
  最近ssm 项⽬做数据库连表查询时,需要查询l_doctor_order_daily_statistic 表的所有数据,同时在 l_account_bank_card 表中如果
a.doctorid=c.account_id 时,则查询该账号的银⾏卡号,如果不存在则只显⽰l_doctor_order_daily_statistic 表中的信息,因为银⾏卡可能有很多张,所以需要合并BANK_CARD_NO 字段。
  查询语句如下:
<select  id ="findList" resultType ="DoctorOrderDailyStatistic">
SELECT
<include refid ="doctorOrderDailyStatisticColumns" />
,GROUP_CONCAT(c.BANK_CARD_NO SEPARATOR ",") AS  "bankCardNo"
FROM  l_doctor_order_daily_statistic a left  join  l_account_bank_card c on  a.doctorid =c.account_id
<include refid ="doctorOrderDailyStatisticJoins" />
<where >
1=1 and  c.STATUS =1
<if  test ="doctorid != null  and  doctorid != ''">
AND  a.doctorid =#{doctorid}
</if >
<if  test ="statisticdate != null  and  statisticdate != ''">
AND  a.statisticdate =#{statisticdate}
</if >
<if  test ="beginDate != null  and  beginDate != ''">
<![CDATA[    AND a.statisticDate >= #{beginDate}  ]]>
</if >
<if  test ="endDate != null  and  endDate != ''">
<![CDATA[    AND a.statisticDate <= #{endDate} ]]>
</if >
</where >
GROUP  BY  a.doctorid
<choose >
<when  test ="page !=null  and  derBy != null  and  derBy != ''">
ORDER  BY  ${derBy}
</when >
<otherwise >
</otherwise >
</choose >
</select >
  下⾯讲⼀下连表查询和合并字段
sql left join 多表连接⼀、连表查询
  连接查询包括合并、内连接、外连接和交叉连接,如果涉及多表查询,了解这些连接的特点很重要。
  1、Union
  UNION 操作符⽤于合并两个或多个 SELECT 语句的结果集。
  UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重复⾏⽽派⽣出⼀个结果表。
  当 ALL 随 UNION ⼀起使⽤时(即 UNION ALL ),不消除重复⾏。
  两种情况下,派⽣表的每⼀⾏不是来⾃ TABLE1 就是来⾃ TABLE2。
  注意:使⽤UNION 时,两张表查询的结果有相同数量的列、列类型相似。
  学⽣表信息(Students ):
  教师表信息(Teachers ):
ID Name
101Mrs Lee
102Lucy
  1)基本UNION 查询,查询学校教师、学⽣的总的信息表,包括ID 和姓名
SELECT  ID,Name FROM  Students
UNION
SELECT  ID,Name FROM  Teachers
  查询结果:
ID Name
101Mrs Lee
101Tom
  2)带条件的UNION查询,也可以查询同⼀张表,查询年龄为18,23岁的学⽣信息
SELECT ID,Name FROM Student WHERE Age=18
UNION
SELECT ID,Name FROM Student WHERE Age=23
  3)查询教师学⽣全部姓名
  因为UNION只会选择不同的值,如果学⽣中和教师中有重名的情况,这就需要UNION ALL
SELECT Name FROM Students
UNION ALL
SELECT Name FROM Teachers
  查询结果:
ID Name
101Tom
102Lucy
101Mrs Lee
102Lucy
  2、INNER JOIN(内连接)
  INNER JOIN(内连接),也成为⾃然连接
  作⽤:根据两个或多个表中的列之间的关系,从这些表中查询数据。
  注意: 内连接是从结果中删除其他被连接表中没有匹配⾏的所有⾏,所以内连接可能会丢失信息。  重点:内连接,只查匹配⾏。
  语法:(INNER可省略)
SELECT fieldlist
FROM table1 [INNER]join table2
lumn
  学⽣表信息(Students):
ID Name Age City MajorID
101Tom20BeiJing10
102Lucy18ShangHai11
  专业信息表(Majors):
ID Name
10English
12Computer
  实例:查询学⽣信息,包括ID,姓名、专业名称
SELECT Students.ID,Students.Name,Majors.Name AS MajorName
FROM Students INNER JOIN Majors
ON Students.MajorID = Majors.ID
  查询结果:
ID Name MajorName
101Tom English
  根据结果可以清晰看到,学⽣Lucy的信息丢失了,只显⽰匹配的⾏。
  但是,inner join也会产⽣重复数据。如果将Majors表的主键约束去掉,可以插⼊重复的ID,如:DELETE FROM Majors
INSERT INTO Majors(ID,Name) VALUES(10,'English')
INSERT INTO Majors(ID,Name) VALUES(10,'Computer')
  继续执⾏上⾯的关联语句,结果为:
ID Name MajorName
101Tom English
101Tom Computer
  如果是LEFT JOIN也会有重复记录,其结果为:
ID Name MajorName
101Tom English
101Tom Computer
102Lucy NULL
  3、外连接
  与内连接相⽐,即使没有匹配⾏,也会返回⼀个表的全集。
  外连接分为三种:左外连接,右外连接,全外连接。对应SQL:LEFT/RIGHT/FULL OUTER JOIN。通常我们省略outer 这个关键字。写成:LEFT/RIGHT/FULL JOIN。
  重点:⾄少有⼀⽅保留全集,没有匹配⾏⽤NULL代替。
  1)LEFT OUTER JOIN,简称LEFT JOIN,左外连接(左连接)
  结果集保留左表的所有⾏,但只包含第⼆个表与第⼀表匹配的⾏。第⼆个表相应的空⾏被放⼊NULL值。
  依然沿⽤内连接的例⼦
  (1)使⽤左连接查询学⽣的信息,其中包括学⽣ID,学⽣姓名和专业名称。
SELECT Students.ID,Students.Name,Majors.Name AS MajorName
FROM Students LEFT JOIN Majors
ON Students.MajorID = Majors.ID
  结果:
ID Name MajorName
101Tom English
102Lucy NULL
  结论:
  通过结果,我们可以看到左连接包含了第⼀张表的所有信息,在第⼆张表中如果没有匹配项,则⽤NULL代替
  2)RIGHT JOIN(right outer join)右外连接(右连接)
  右外连接保留了第⼆个表的所有⾏,但只包含第⼀个表与第⼆个表匹配的⾏。第⼀个表相应空⾏被⼊NULL值。
  右连接与左连接思想类似。只是第⼆张保留全集,如果第⼀张表中没有匹配项,⽤NULL代替依然沿⽤内链接的例⼦,只是改为右连接  (1)使⽤右连接查询学⽣的信息,其中包括学⽣ID,学⽣姓名和专业名称。
SELECT Students.ID,Students.Name,Majors.Name AS MajorName
FROM Students RIGHT JOIN Majors
ON Students.MajorID = Majors.ID
  查询结果:
ID Name MajorName
101Tom English
NULL NULL Computer
  通过结果可以看到,包含了第⼆张表Majors的全集,Computer在Students表中没有匹配项,就⽤NULL代替。
  3)FULL JOIN (FULL OUTER JOIN,全外连接)
  全外连接,简称:全连接。会把两个表所有的⾏都显⽰在结果表中
  1)使⽤全连接查询学⽣的信息,其中包括学⽣ID,学⽣姓名和专业名称。
SELECT Students.ID,Students.Name,Majors.Name AS MajorName
FROM Students FULL JOIN Majors
ON Students.MajorID = Majors.ID
  查询结果:
ID Name MajorName
101Tom English
102Lucy NULL
NULL NULL Computer
  包含了两张表的所有记录,没有记录丢失,没有匹配的⾏⽤NULL代替。
  4、CROSS JOIN(交叉连接)
  交叉连接。交叉连接返回左表中的所有⾏,左表中的每⼀⾏与右表中的所有⾏组合。交叉连接也称作笛卡尔积。
  简单查询两张表组合,这是求笛卡⼉积,效率最低。
  笛卡⼉积:笛卡尔乘积,也叫直积。假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1), (b,2)}。可以扩展到多个集合的情况。类似的例⼦有,如果A表⽰某学校学⽣的集合,B表⽰该学校所有课程的集合,则A与B的笛卡尔积表⽰所有可能的选课情况。
 1)交叉连接查询学⽣的信息,其中包括学⽣ID,学⽣姓名和专业名称。
SELECT Students.ID,Students.Name,Majors.Name AS MajorName
FROM Students CROSS JOIN Majors
  查询结果:
ID Name MajorName
101Tom English
102Lucy English
101Tom Computer
102Lucy Computer
  2)查询多表,其实也是笛卡⼉积,与CROSS JOIN等价,以下查询同上述结果⼀样。
  这个可能很常见,但是⼤家⼀定要注意了,这样就查询了两张表中所有组合的全集。
SELECT Students.ID,Students.Name,Majors.Name AS MajorName
FROM Students,Majors
  3)加了查询条件
  注意:在使⽤CROSS JOIN关键字交叉连接表时,因为⽣成的是两个表的笛卡尔积,因⽽不能使⽤ON关键字,只能在WHERE⼦句中定义搜索条件。
SELECT Students.ID,Students.Name,Majors.Name AS MajorName
FROM Students CROSS JOIN Majors
WHERE Students.MajorID = Majors.ID
  查询结果:
ID Name MajorName
101Tom English
  查询结果与INNER JOIN⼀样,但是其效率就慢很多了。
⼆、重复记录同⼀字段的合并
  ⼀个字段可能对应多条数据,⽤mysql实现将多⾏数据合并成⼀⾏数据
  例如:⼀个活动id(activeId)对应多个模块名(modelName),按照⼀般的sql语句:
SELECT am.delName
FROM activemodel am
JOIN  model m
delId = m.modelId
ORDER BY am.activeId
  查询结果:
activeId modelname
1吃饭
1游泳
3⾏车
4唱歌
4打球
修改过后的sql语句,查询后如图:
SELECT am.activeId,GROUP_delName SEPARATOR ',') modelName
FROM activemodel am
JOIN model m
delId
WHERE m.valid=1
GROUP BY am.activeId
  查询结果:
activeId modelName
1吃饭,游泳
3⾏车
4唱歌,打球
1.GROUP_CONCAT()中的值为你要合并的数据的字段名;
 SEPARATOR 函数是⽤来分隔这些要合并的数据的;
 ' '中是你要⽤哪个符号来分隔;
2.必须要⽤GROUP BY 语句来进⾏分组管理,不然所有的数据都会被合并成⼀条记录

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。