这里使用postgreSQL数据库
-- Create the table CREATE TABLE intense.t_stu ( id NUMERIC(24), name CHARACTER VARYING(20), gender NUMERIC(1), grade NUMERIC(4) ); -- Truncate the table truncate table intense.t_stu; -- Insert data insert into intense.t_stu values(1,'John',1,93); insert into intense.t_stu values(2,'Lisa',0,94); insert into intense.t_stu values(3,'John2',1,83); insert into intense.t_stu values(4,'Lisa2',0,84); insert into intense.t_stu values(5,'John3',1,73); insert into intense.t_stu values(6,'Lisa3',0,74); insert into intense.t_stu values(7,'John4',1,63); insert into intense.t_stu values(8,'Lisa4',0,64); insert into intense.t_stu values(9,'John5',1,53); insert into intense.t_stu values(10,'Lisa5',0,54); insert into intense.t_stu values(11,'John6',1,103); insert into intense.t_stu values(12,'Lisa6',0,104); -- Get the data needed SELECT * FROM intense.t_stu a WHERE ( SELECT COUNT(*) FROM intense.t_stu WHERE gender=a.gender AND grade > a.grade) < 5 ORDER BY a.grade DESC
a表按照grade由高到低排列,并和t_stu连接,条件是gender相等并且grade大于a表的grade(返回10条记录,count=4略去):
如果不考虑gender,只求前5名:
select * from intense.t_stu a where (select count(*) from intense.t_stu where grade > a.grade) < 5 order by a.grade desc
2. 有一张表t_game,记录了游戏玩家的id,游戏玩家名name,和每个玩家玩的游戏game,请找出玩游戏最多的那个玩家。
-- Create the table CREATE TABLE intense.t_game( id numeric(24), name character varying(20), game character varying(20) ); -- Truncate the table truncate table intense.t_game; -- Insert data insert into intense.t_game values(1,'John','game'); insert into intense.t_game values(2,'Lisa','game2'); insert into intense.t_game values(3,'Jack','game3'); insert into intense.t_game values(4,'Jim','game4'); insert into intense.t_game values(3,'Jack','game5'); insert into intense.t_game values(5,'Eric','game6'); insert into intense.t_game values(1,'John','game7'); insert into intense.t_game values(3,'Jack','game8'); insert into intense.t_game values(6,'Nicolas','game9'); -- Get the data needed -- MySQL, postgreSQL SELECT id, name FROM intense.t_game GROUP BY id, name ORDER BY COUNT(*) DESC LIMIT 1 -- SQL Server SELECT TOP 1 id, name FROM intense.t_game GROUP BY id, name ORDER BY COUNT(*) DESC -- Oracle
3. CASE WHEN 示例:
-- CASE后面跟字段 SELECT ( CASE account WHEN 1 THEN 0.5 WHEN 0 THEN 0 ELSE FLOAT(account) END) AS account_val FROM tb_account; -- 如果判断表达式比较复杂,把字段放到每个判断表达式中 SELECT ( CASE WHEN account IS NULL THEN 0 WHEN account > 0 THEN FLOAT(account) ELSE -1 END) AS account_val FROM tb_account;
注:这里的float函数是DB2数据库支持的,其它数据库请改成相应的函数。
4. 同步两个表中的某些字段:
表连接关键字(LEFT JOIN, INNER JOIN, RIGHT JOIN等)常常用于查询语句,其实也可以用于更新和删除语句:
在DB2和Oracle上:
UPDATE tableB b SET ( COL_1, COL_2, COL3 ) = ( SELECT COL_4, COL_5, COL_6 FROM tableA a WHERE a.ID = b.ID) WHERE -- WHERE能限定范围,提高性能;如果数据量较大,需要给两张表的连接字段加上索引 ID IN ( SELECT ID FROM tableA a WHERE a.ID = b.ID)
如果tableA中有重复的记录,会导致更新失败,因为数据库不知道该更新为哪个值:
解决思路:限定匹配值只有一个:
-- DB2 UPDATE tableB b SET ( COL_1, COL_2, COL3 ) = ( SELECT COL_4, COL_5, COL_6 FROM tableA a WHERE a.ID = b.ID ORDER BY CREATE_TIME DESC FETCH FIRST 1 ROWS ONLY) ID IN ( SELECT ID FROM tableA a WHERE a.ID = b.ID)
SQL Server上:
UPDATE b SET COL_1=a.COL_4, COL_2=a.COL_5, COL_3=a.COL_6 FROM tableA a LEFT JOIN tableB b ON a.ID = b.ID -- 也可以写成: UPDATE b SET COL_1=a.COL_4, COL_2=a.COL_5, COL_3=a.COL_6 FROM tableA a, tableB b WHERE a.ID = b.ID