2015-10-23 45 views
0

我有一個表表1其中有5列這樣MySQL的內部連接發生變化的記錄

| ID | Name | V1 | V2 | V3 | 
| 1 | A | 103 | 507 | 603 | 
| 2 | B | 514 | 415 | 117 | 

和另一個表表2其中有這樣

| Values | Rooms | 
| 103 | ABC | 
| 507 | DEF | 
| 603 | GHI | 
| 514 | JKL | 
| 415 | MNO | 
| 117 | PQR | 

我值的順序我正在運行加入查詢以獲得來自的房間表2加入了表1作爲

SELECT t2.values, t2.rooms, t1.Name FROM Table2 t2 
INNER JOIN Table1 t1 ON t1.V1 = t2.Values 
        OR t1.V2 = t2.Values 
        OR t1.V3 = t2.Values; 

此查詢獲取結果,但按t2.values的升序排列。我不想改變任何順序。我只是想得到結果在任何Table1有價值。

| Values | Rooms | Names | 
| 103 | ABC | A | 
| 117 | PQR | B | 
| 415 | MNO | B | 
| 507 | DEF | A | 
| 514 | JKL | B | 
| 603 | GHI | A | 

以上的結果,根據T2.Values有序並且這些值來形成t1.V1,t1.V2,T1.V3。我不想要訂單結果。我想要的結果是根據t1.V1,t1.V2,T1.V3值。如果我們在表1 看到值將是103,507,603,514,415,117,因此其結果應該是

| Values | Rooms | Names | 
| 103 | ABC | A | 
| 507 | DEF | A | 
| 603 | GHI | A | 
| 415 | MNO | B | 
| 514 | JKL | B | 
| 117 | PQR | B | 

我希望我做了我的解釋不知何故更好。請如果它仍然不清楚讓我允許編輯它更多。

由於paxdiablo建議,我試着添加ORDER BY t1.name,但那不是排序和結果是一樣的。爲什麼?

+1

這就是如何有用。如果您想要特定訂單,請始終使用ORDER BY子句。 – jarlh

+0

@jarlh如果我不想要任何特定的訂單,該怎麼辦?任何方式在那裏? –

+1

簡單,只是跳過ORDER BY ... – jarlh

回答

2

我知道你已經接受了答案,但像你想通過他們的順序排序在我看來表1中的ID,然後列的順序(v1,v 2,v3),你已經匹配了。在這種情況下,這樣的事情應該工作:

SELECT t2.`values`, t2.rooms, t1.Name FROM Table2 t2 
INNER JOIN Table1 t1 ON t1.V1 = t2.`values` 
        OR t1.V2 = t2.`values` 
        OR t1.V3 = t2.`values` 
ORDER BY 
    t1.id, 
    CASE 
     WHEN t1.v1 = t2.`values` THEN 1 
     WHEN t1.v2 = t2.`values` THEN 2 
     WHEN t1.V3 = t2.`values` THEN 3 
    END 

(請注意,我引用values,因爲它是在SQL關鍵字...)

什麼我在這裏做的是:

首先,我通過t1.id進行排序,這會根據t1表中的行獲得粗略的排序順序。

然後,我使用CASE語句添加了第二種排序,其中Values列在結果行中匹配。對於查詢結果的每一行,如果結果是由t1.v1t2.values之間的匹配產生的,則CASE語句的計算結果爲1.如果結果是因爲t1.v2t2.values之間的匹配,則得到2.如果結果是因爲t1.v3t2.values之間的匹配,然後我們得到3

所以總體排序是基於第一行的順序在t1,然後內,其中列得到t1之間匹配順序上和t2爲您的結果中的每一行,這似乎是要求(雖然很難把詞寫入!)

+0

太棒了!馬特你給了我要求的確切答案。實際上paxdiablo的答案不是我要求的答案,但它教了很多,並以其他方式解決了問題。請您對ORDER BY和CASE函數有所瞭解。請解釋它在CASE中實際做了什麼,它的目的。 –

+0

謝謝馬特。我從你那裏學到了新東西。非常感謝 –

4

我只是想得到任何Table1有值的結果。

這是你犯過錯的地方。至少就SQL而言,並不是的訂單。表格是無序集合,當您提取數據時(如果您願意),您可以將強加給

SQL語句select絕對做不保證在返回結果,除非你專門使用order bygroup by的順序。即使select * from table1也可以按照DBMS認爲合適的順序返回行,以便將它們提供給您。

如果你想要一個特定的順序,你需要明確地要求。例如,如果您希望他們按房間名稱排序,請在查詢結尾處輸入order by t1.name。儘管我可能會全力以赴,並使用次要排序順序,請使用order by t1.name, t2.rooms

或者,要對這些值進行排序,請添加order by t2.values


例如,衝壓此架構/數據爲SQLFiddle

create table table1(
    id integer, 
    name varchar(10), 
    v1 integer, 
    v2 integer, 
    v3 integer); 
insert into table1 (id,name,v1,v2,v3) values (1,'a',103,507,603); 
insert into table1 (id,name,v1,v2,v3) values (2,'b',514,415,117); 

create table table2 (
    val integer, 
    room varchar(10)); 
insert into table2(val,room) values (103,'abc'); 
insert into table2(val,room) values (507,'def'); 
insert into table2(val,room) values (603,'ghi'); 
insert into table2(val,room) values (514,'jkl'); 
insert into table2(val,room) values (415,'mno'); 
insert into table2(val,room) values (117,'pqr'); 

,然後執行:

select t2.val, t2.room, t1.name from table2 t2 
inner join table1 t1 on t1.v1 = t2.val 
        or t1.v2 = t2.val 
        or t1.v3 = t2.val 

爲我們提供了一個任意排序(它可能喜歡它的訂貨由內namerooms但不能保證):

| val | room | name | 
|-----|------|------| 
| 103 | abc | a | 
| 507 | def | a | 
| 603 | ghi | a | 
| 514 | jkl | b | 
| 415 | mno | b | 
| 117 | pqr | b | 

當我們改變這種排序上的兩個下行鍵order by t1.name desc, t2.room desc,我們可以看到它基於該重新排序:

| val | room | name | 
|-----|------|------| 
| 117 | pqr | b | 
| 415 | mno | b | 
| 514 | jkl | b | 
| 603 | ghi | a | 
| 507 | def | a | 
| 103 | abc | a | 

最後,改變排序子句order by t2.val asc,我們得到它在價值秩序:

| val | room | name | 
|-----|------|------| 
| 103 | abc | a | 
| 117 | pqr | b | 
| 415 | mno | b | 
| 507 | def | a | 
| 514 | jkl | b | 
| 603 | ghi | a | 

最後,如果你的目的是通過列的順序每一行來訂購吧(所以順序是從左到右v1,v2,v3,你可以引入一個人工排序鍵,或者通過使用case語句來根據匹配的列進行選擇,或者通過運行多個可能更有效的查詢:

  • 你不執行每行的功能,它往往不規模非常好;而在更大的DBMS」
  • ,它們可以被並行化。

的多個查詢選項會去是這樣的:

select 1 as minor, t2.val as val, t2.room as room, t1.name as name from table2 t2 
    inner join table1 t1 on t1.v1 = t2.val 
union all select 2 as minor, t2.val as val, t2.room as room, t1.name as name from table2 t2 
    inner join table1 t1 on t1.v2 = t2.val 
union all select 3 as minor, t2.val as val, t2.room as room, t1.name as name from table2 t2 
    inner join table1 t1 on t1.v3 = t2.val 
order by name, minor 

,併產生:

| minor | val | room | name | 
|-------|-----|------|------| 
|  1 | 103 | abc | a | 
|  2 | 507 | def | a | 
|  3 | 603 | ghi | a | 
|  1 | 514 | jkl | b | 
|  2 | 415 | mno | b | 
|  3 | 117 | pqr | b | 

你可以看到有它使用name作爲主鍵和值的位置在行中作爲次要關鍵。

現在有些人可能認爲它一個醜陋的方式引進一個假的列排序,但它是爲提高性能久經考驗的方法。但是,你不應該相信我(或任何人)。我的主要口頭優化是措施,不要猜測。

+0

那麼你有什麼想法,我怎麼能實現我的列順序不受干擾的結果?我不在乎是否訂購了其他專欄。我只是不希望訂單或價值改變。 –

+0

@AbdulJabbarWebBestow爲什麼不'ORDER BY Rooms'?當然,除非提供的值是虛擬的。在這種情況下,您必須向您的table2添加排序值。 –

+0

Nup需要根據V1,V2和V3的列值對結果進行排序。 –

0

以及查詢使用值升序排序表 - 如「103 415等......」但你希望他們採取他們在實際表中排序的順序,即「 103比507比603等」,這是排序的方式,他們已經被插入,你只是想保留排序的順序..你可以做到這一點的一種可能的方式是使用在第二臺額外的時間戳字段可跟蹤插入時間完成,因此您可以使用時間戳,如「ORDER BY時間戳」在您的查詢..