天天看點

mysql中union all使用注意點_mysql中union和union all的差別和注意點

昨天有個功能要實作排行效果,而且是随機按照某些字段的總值,但是第一個又要不一樣,因為第一個人給了錢,是以要排第一。

打個比方吧,表(userinfo)中有這幾個字段:username,isvalid,givedmoney,sumip,dayip,monthip,visitcount,regdate

現在要實作顯示排行前10位使用者,

出現在排行第一位的要是givedmoney為1的使用者(表示給了錢), 而且isvalid為1(表示通過認證)

其它的9個使用者呢,要在字段(sumip,dayip,monthip,visitcount)中随機選擇一個作為排序的依據

這樣的sql語句改怎麼寫呢?

下面是我的答案:

$arr_orderby=array("sumip","dayip","monthip","visitcount");

$orderby_filed=$arr_orderby(array_rand($arr_orderby) ); //得到随機字段

$sql="(select username,".$orderby_filed." from userinfo where isvalid=1 and givedmoney=1 limit 1) union (select username,".$orderby_filed." from userinfo where isvalid=1 and givedmoney!=1 limit 9) order by rand(),".$orderby_filed." desc";

?>

這裡需要注意的幾點是,

1:union前後的select字段一定要一樣,而且順序要一樣,如果你不是select * 的話

2:第二個select中,試試limit 9和limit 10有什麼不一樣的效果

union和union all的差別就是後面能踢出重複的結果,如果确定表中沒有重複的字段,建議使用union all

一 UNION文法

代碼 複制代碼

SELECT ...

UNION [ALL | DISTINCT]

SELECT ...

[UNION [ALL | DISTINCT]

SELECT ...]

SELECT ...

UNION [ALL | DISTINCT]

SELECT ...

[UNION [ALL | DISTINCT]

SELECT ...]

UNION用于把來自許多SELECT語句的結果組合到一個結果集合中。 (

如果你要将多個表的查詢結果進行合并輸出比如說 群組消息跟個人消息表是分離的但是想一起提取出來并顯示的話就可以如此處理。通過UNION聯合查詢出來即可)

列于每個SELECT語句的對應位置的被選擇的列應具有相同的類型(

前提條件是兩個SELECT出來的列類型要保持一樣的才行!)。(例如,被第一個語句選擇的第一列應和被其它語句選擇的第一列具有相同的類型。)在第一個SELECT語句中被使用的列名稱也被用于結果的列名稱。

SELECT語句為正常的選擇語句,但是受到如下的限定:

·          隻有最後一個SELECT語句可以使用INTO OUTFILE。

·          HIGH_PRIORITY不能與作為UNION一部分的SELECT語句同時使用。如果您對第一個 SELECT指定了HIGH_PRIORITY,則不會起作用。如果您對其它後續的SELECT語句指定了HIGH_PRIORITY,則會産生文法錯誤。

如果您對UNION不使用關鍵詞ALL,則所有傳回的行都是唯一的,如同您已經對整個結果集合使用了DISTINCT。如果您指定了ALL,您會從所有用過的SELECT語句中得到所有比對的行。

DISTINCT關鍵詞是一個自選詞,不起任何作用,但是根據SQL标準的要求,在文法中允許采用。(在MySQL中,DISTINCT代表一個共用體的預設工作性質。)

您可以在同一查詢中混合UNION ALL和UNION DISTINCT。被混合的UNION類型按照這樣的方式對待,即DISTICT共用體覆寫位于其左邊的所有ALL共用體。DISTINCT共用體可以使用UNION DISTINCT明确地生成,或使用UNION(後面不加DISTINCT或ALL關鍵詞)隐含地生成。

如果您想使用ORDER BY或LIMIT子句來對全部UNION結果進行分類或限制,則應對單個地SELECT語句加圓括号,并把ORDER BY或LIMIT放到最後一個的後面。以下例子同時使用了這兩個子句:

代碼 複制代碼

(SELECT a FROM tbl_name WHERE a=10 AND B=1)UNION(SELECT a FROM tbl_name WHERE a=11 AND B=2)ORDER BY a LIMIT 10;(

如果想要實作分頁的話可以這樣處理  将兩個查詢的結果集當作是一個大的結果集處理然後再對此大的結果集進行LIMIT處理即可實作!)好好好 ~!

(SELECT a FROM tbl_name WHERE a=10 AND B=1)UNION(SELECT a FROM tbl_name WHERE a=11 AND B=2)ORDER BY a LIMIT 10;

這種ORDER BY不能使用包括表名稱(也就是,采用tbl_name.col_name格式的名稱)列引用。可以在第一個SELECT語句中提供一個列别名,并在 ORDER BY中參閱别名,或使用列位置在ORDER BY中參閱列。(首選采用别名,因為不建議使用列位置。)

另外,如果帶分類的一列有别名,則ORDER BY子句必須引用别名,而不能引用列名稱。以下語句中的第一個語句必須運作,但是第二個會運作失敗,出現在'order clause'中有未知列'a'的錯誤:

代碼 複制代碼

(SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY b;(SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY a;To apply ORDER BY or LIMIT to an individual SELECT, place the clause inside the parentheses that enclose the SELECT:

(SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY b;(SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY a;To apply ORDER BY or LIMIT to an individual SELECT, place the clause inside the parentheses that enclose the SELECT:

為了對單個SELECT使用ORDER BY或LIMIT,應把子句放入圓括号中。圓括号包含了SELECT:

代碼 複制代碼

(SELECT a FROM tbl_name WHERE a=10 AND B=1 ORDER BY a LIMIT 10)UNION(SELECT a FROM tbl_name WHERE a=11 AND B=2 ORDER BY a LIMIT 10);

(SELECT a FROM tbl_name WHERE a=10 AND B=1 ORDER BY a LIMIT 10)UNION(SELECT a FROM tbl_name WHERE a=11 AND B=2 ORDER BY a LIMIT 10);

二 執行個體擴充

union可以對同一個表的兩次查詢聯合起來. 這樣做的益處也非常明顯, 比如在blog應用中, 可以利用一條sql語句實作置頂blog和普通blog的分頁顯示.

代碼 複制代碼

(

SELECT *

FROM `blog`

WHERE top=1

ORDER BY created DESC

)

UNION (

SELECT *

FROM `blog`

WHERE top = 0

ORDER BY created DESC

)LIMIT 2 , 3

注:union要求聯合的兩個表所要查找的資料列要一樣多,如果一個表中沒有另一個表的字段,可以用NULL代替。