簡體   English   中英

基於同一表上的值在同一行上返回多個值

[英]Returning multiple values on the same row, based on a value on the same table

我已經很困惑了一段時間,一直試圖根據其他結果從我們的一個表中獲取結果,並且每個值都沒有返回多行,這很難為我解釋,所以我舉一個例子。

我們有一個值,例如APPLES。 每個蘋果都有自己的序列號SERIAL。 對於某些APPLES,有多個(最多6個)SERIAL值。

ID      APPLE       SERIAL
2052    5035        1
2055    5035        4
2058    5035        8
2070    5040        5

在我的結果中,我想返回每個APPLE一次,並將所有序列分配給它,例如:

APPLE   SERIAL_1    SERIAL_2    SERIAL_3    SERIAL_4
5035    1           4           8
5040    5

我試圖進行一個查詢,該查詢基本上將同一張表連接了4次,並說serial_x不存在(其他序列)。 問題是它將產生多個結果,如下所示:

APPLE   SERIAL_1    SERIAL_2    SERIAL_3    SERIAL_4
5035    1           4           8
5035    1           8           4
5035    4           1           8
5035    4           8           1
5035    8           1           4
5035    4           4           1
5040    5

這顯然是因為具有不同序列號的Apple 5035在表中出現了多次,並且它獲得了分配給它的三個序列號的所有可能組合。 我敢肯定有一個簡單的方法可以做到這一點,但是我已經嘗試了很長時間了,但是並沒有取得很好的結果。 有人可以協助嗎?

您可以嘗試一下,它雖然不優雅,但可以工作:

SELECT DISTINCT t1.apple, 
    (SELECT serial FROM your_table
     WHERE apple = t1.apple
     ORDER BY serial LIMIT 0,1) serial_1,
    (SELECT serial FROM your_table
     WHERE apple = t1.apple
     ORDER BY serial LIMIT 1,1) serial_2,
    (SELECT serial FROM your_table
     WHERE apple = t1.apple
     ORDER BY serial LIMIT 2,1) serial_3,
    (SELECT serial FROM your_table
     WHERE apple = t1.apple
     ORDER BY serial LIMIT 3,1) serial_4,
    (SELECT serial FROM your_table
     WHERE apple = t1.apple
     ORDER BY serial LIMIT 4,1) serial_5,
    (SELECT serial FROM your_table
     WHERE apple = t1.apple
     ORDER BY serial LIMIT 5,1) serial_6
FROM your_table t1

游戲有些晚了,但是由於在Oracle中使用PIVOT子句沒有答案,因此可能仍然很有趣。

SELECT *
FROM (
  SELECT apple, serial
  FROM fruits
) t
PIVOT ( 
  max(serial) for serial in (1,2,3,4,5,6)
) 

SQLFiddle示例: http ://sqlfiddle.com/#!4/3cede/2

您可以嘗試使用GROUP_CONCAT聚合函數和GROUP BY APPLE

SELECT 
    a.APPLE,
    GROUP_CONCAT(DISTINCT s.SERIAL) AS serials
FROM 
    apples a
    LEFT JOIN apples s ON s.APPLE = a.APPLE
GROUP BY a.APPLE


在MySQL中測試:

mysql> select * from apples;
+------+-------+--------+
| ID   | APPLE | SERIAL |
+------+-------+--------+
| 2052 |  5035 |      1 |
| 2055 |  5035 |      4 |
| 2058 |  5035 |      8 |
| 2070 |  5040 |      5 |
+------+-------+--------+
4 rows in set (0.00 sec)

mysql> SELECT 
    ->     a.APPLE,
    ->     GROUP_CONCAT(DISTINCT s.SERIAL) AS serials
    -> FROM 
    ->     apples a
    ->     LEFT JOIN apples s ON s.APPLE = a.APPLE
    -> GROUP BY a.APPLE;
+-------+---------+
| APPLE | serials |
+-------+---------+
|  5035 | 1,4,8   |
|  5040 | 5       |
+-------+---------+
2 rows in set (0.00 sec)

mysql> 

Oracle 11g具有LISTAGG功能 ,該功能似乎可以滿足您的需求。 我這里沒有11g,但以下內容應該很接近:

SELECT apple, listagg(serial, ',') WITHIN GROUP (ORDER BY serial) "Serial Numbers"
  FROM tbl
 GROUP BY apple;

您沒有為每個序列項獲得漂亮的列標題,但是它應該可以工作。

我會做這樣的事情:

with data as (
    select 2052 id, 5035 apple, 1 serial from dual union all
    select 2055 id, 5035 apple, 4 serial from dual union all
    select 2058 id, 5035 apple, 8 serial from dual union all
    select 2070 id, 5040 apple, 5 serial from dual
)
select
    apple,
    serial_1,
    serial_2,
    serial_3,
    serial_4,
    serial_5,
    serial_6
from (
    select
        apple,
        serial as serial_1,
        lead(serial,1) over (partition by apple order by serial) as serial_2,
        lead(serial,2) over (partition by apple order by serial) as serial_3,
        lead(serial,3) over (partition by apple order by serial) as serial_4,
        lead(serial,4) over (partition by apple order by serial) as serial_5,
        lead(serial,5) over (partition by apple order by serial) as serial_6,
        row_number() over (partition by apple order by serial) rn
    from data
)
where rn = 1;

顯然,您不需要WITH塊,因為您可以使用實際表,因此您的查詢將從SELECT開始。

這將給出以下輸出:

  APPLE SERIAL_1 SERIAL_2 SERIAL_3 SERIAL_4 SERIAL_5 SERIAL_6 

  5035 1 4 8 5040 5 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM