Linq To Entity中Union的使用


SQL Union基礎知識:

    參考文獻Reference: http://www.w3school.com.cn/sql/sql_union.asp

SQL UNION 操作符

    UNION 操作符用於合併兩個或多個 SELECT語句的結果集

    請注意,UNION 內部的 SELECT 語句必須擁有相同數量的列。列也必須擁有相似的數據類型,但列名可以不同。同時,每條 SELECT 語句中的列的順序必須相同。

SQL UNION 語法

  1. SELECT column_name(s) FROM table_name1
  2. UNION
  3. SELECT column_name(s) FROM table_name2

    註釋:默認地,UNION操作符選取不同的值。如果允許重複的值,請使用UNION ALL。

SQL UNION ALL 語法

  1. SELECT column_name(s) FROM table_name1
  2. UNION ALL
  3. SELECT column_name(s) FROM table_name2

    另外,UNION 結果集中的列名總是等於 UNION 中第一個SELECT 語句中的列名。

    


下面的例子中使用的原始表

UserInfo:


LoginUser:


使用 UNION 命令

實例

    列出所有不同的僱員名:
  1.     
  2. select Name from UserInfo
  3. union
  4. select Name from LoginUser

結果



    註釋:這個命令無法列出在兩張表所有的用戶名信息中。UNION 命令只會選取不同的值。


UNION ALL

    UNION ALL 命令和 UNION 命令幾乎是等效的,不過 UNION ALL 命令會列出所有的值

  1. select Name from UserInfo      union all    
  2.       select Name from LoginUser
  3. 使用 UNION ALL 命令

實例:

    列出所有的用戶信息:

結果



union all 和order by

    Reference: http://www.linuxidc.com/Linux/2011-05/35796.htm  union all 和 order by

    有時候,我們會將經過排序(order by)後的結果集與其他經過排序的結果集進行合併(union or union all),比如:     

  1. select * from tb where length(id)=5 order by id desc
  2. union all
  3. select * from tb where length(id)=10 order by id asc

    通常情況下,上面的查詢將會得到下面的錯誤提示:    
ORA-00933: SQL command not properly ended     
    錯誤指向union關鍵字這裏。

    下面我們來看一個具體的實例:         

  1. create table t as
  2. select 'china' col_1,'america' col_2,'canada' col_3,-1 status from dual union all
  3. select '花生','瓜子','綠豆',0 from dual union all
  4. select '牙膏','牙刷','杯子',3 from dual union all
  5. select '芍藥','牡丹','月季',1 from dual union all
  6. select '優樂美','香飄飄','炸雞',2 from dual
    需求:有如上表t,status字段的取值範圍:[-1,3],我們想要做的是,按照這樣的方式排序0,1,2,3,-1    
    解法:更具題義,我們需要將status分爲兩個區域(>0 和<0) ,然後分別對每一個區域內的數據進行order by排序 ,於是有下面的查詢    
  1. select col_1,col_2,col_3,status
  2. from t
  3. where status >= 0
  4. order by status --1
  5. union
  6. select col_1,col_2,col_3,status
  7. from t
  8. where status < 0
  9. order by status --2
    不幸的是,正如剛剛開始時我提示的一樣,我們得到了下面的錯誤提示:     
ORA-00933: SQL command not properly ended     
    如果將第一個select語句的order by子句去掉,得到的又不是我們想要的結果,此時得到的結果是將整個結果集進行排序。如果將兩個排序子句都去掉的話,雖然按照status爲正負數分開了,但是沒有排序    
    下面我們來看看正確的答案吧!   
解法一:  如果是union all前後分別排序的話,在外面包一層select就起作用了。
  1. select from 
  2. (select  TOP (100) PERCENT, col_1,col_2,col_3,status
  3. from t
  4. where status >= 0
  5. order by status)
  6. union all
  7. select *  from 
  8. (select TOP (100) PERCENT, col_1,col_2,col_3,status
  9. from t
  10. where status < 0
  11. order by status)
結果:   
COL_1  COL_2  COL_3      STATUS     
------       -------    ------        ----------     
花生       瓜子    綠豆           0     
芍藥       牡丹    月季           1     
優樂美  香飄飄  炸雞          2    
牙膏       牙刷    杯子           3     
china     americacanada      -1    


解法二:   

  1. select * from t
  2. order by
  3. decode(status,
  4. -1,1,
  5. 3,2,
  6. 2,3,
  7. 1,4,
  8. 0,5) desc

    這可是一個很妙的排序,本人首次看到在order by語句中可以使用decode()函數來排序。

    同理,我們也可以使用case語句來排序:   

解法三:   
  1. select * from t
  2. order by
  3. case status
  4. when -1 then 5
  5. when 3 then 4
  6. when 2 then 3
  7. when 1 then 2
  8. else 1
  9. end

    最後,union和unionall中都支持orderby和groupby排序和分組子句 

    union all 和order by, 兩個連用的話會是,查看下一段資料。



另外一段資料:union all and order by

    這段資料裏面涉及到的英文資料的鏈接很好。

    Reference: http://blog.sina.com.cn/s/blog_6cb0deff0100t4l8.html

    遇到的問題:
    一個sql中,union了幾個子查詢。單獨執行每個子查詢都沒問題,但union後執行,報
ORA-00904: "xxx": invalid identifier

關於union的使用:
    SQL: UNION Query:
http://www.techonthenet.com/sql/union.php
    SQL: UNION ALL Query:
http://www.techonthenet.com/sql/union_all.php

    前面已經提到:union的各個子查詢要有相同數量的列,且對應位置的列必須具有相同的數據類型;但列的名字可以不同。
    thediffrence between UNION ALL and UNION is that UNION will attempt to eliminateduplicates.

關於order by的使用:
    SQL: ORDER BY Clause
http://www.techonthenet.com/sql/order_by.php
    Example #3
    You can also sort by relative position in the result set, where the first fieldin the result set is 1. The next field is 2, and so on.

  1. SELECT supplier_city
  2. FROM suppliers
  3. WHERE supplier_name = 'IBM'
  4. ORDER BY 1 DESC;

    This wouldreturn all records sorted by the supplier_city field in descending order, sincethe supplier_city field is in position #1 in the result set.

union中order by的使用:
    You have to use the Order By at the end of ALL the unions.
    the ORDER BY is considered to apply to the whole UNION result(it's effectivelygot lower binding priority than the UNION). 
    The ORDER BY clause just needs to be the last statement, after you've done allyour unioning. You can union several sets together, then put an ORDER BY clause after the last set.
    所以,能在union的最後一個子查詢中使用order by,而這個order by是針對整個union後的結果集的So:
    如果unoin的幾個子查詢列名不同,如

  1. select supplier_id, supplier_name
  2. from suppliers
  3. UNION
  4. select company_id, company_name
  5. from companies
  6. ORDER BY ?;

    這裏的問號如果是company_name,則執行整個查詢會報“company_name:invalididentifier”(當然,單獨執行第二個含orderby的子查詢是沒有問題的);這是因爲unioning後結果集的列名是以第一個參加union的子查詢的列名爲準的;orderby針對的是整個unioning後的結果集。對整個查詢結果來說,無”company_name“這個字段。
    如果是supplier_name,則單獨執行第二個含order by的子查詢是會報“supplier_name:invalididentifier”的,而執行整個查詢是沒有問題的,因爲orderby針對的是unioning後的整個結果集,而這“整個結果集”是有supplier_name這列的(以第一個union子查詢的列名作爲unioning後整個結果集的列名)

    爲了避免這樣事情的發生,可以:
solution#1: 使用列序號代替實際列名。如:

  1. select supplier_id, supplier_name
  2. from suppliers
  3. UNION
  4. select company_id, company_name
  5. from companies
  6. ORDER BY 2;

solution#2:爲unoin的各個子查詢使用相同的列名,如:

  1. select supplier_id as id, supplier_name as name
  2. from suppliers
  3. UNION
  4. select company_id as id, company_name as name
  5. from companies
  6. ORDER BY name;

這樣,不管是執行整個查詢還是單獨執行包含orderby的最後一個union子查詢,都不會有問題。

Q&A:
http://p2p.wrox.com/sql-language/9505-order-union.html
Q:

引用

I have two tables, TableA and TableB defined as follows,

TableA
A1 int
A2 int
A3 int

TableB
B1 int
B2 int
B3 int

If I try to run this query, SQL Server says syntex failed at the Order By clouse. Is such Order by not allowed in SQL, Any other way to achieve this?

  1. (Select A1, A2 from TableA)
  2. Union All
  3. (Select B1, B2 from TableB Order by B3)

Any help will be appreciated.


A:

引用

    First of all, you can not order by a column that is not included in your SELECT list(我注:這句話是錯誤的;可以order by一個不在select列表中的column).Secondly, when performing a UNION query the ORDER BY clause must be(我注:not “must be”) a column index not a column name, because a UNION query does not have column headings(although SQL Server(我注:此處泛指DBMS) pretends that it has by picking the column names used in the first query although this is not ANSIcompliant]). Assuming you want to order the second column (A2 and B2) your query should look like this:
Code:

  1. SELECT A1, A2
  2. FROM TableA
  3. UNION ALL
  4. SELECT B1, B2
  5. FROM TableB
  6. ORDER BY 2

Conceptually, ORDER BY works by producing the final query table with all the queries joined together (if it is a UNION query), then it orders the query results and does not care about what is in the database.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章