Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 基于同一表上的值在同一行上返回多个值_Sql_Oracle_Pivot - Fatal编程技术网

Sql 基于同一表上的值在同一行上返回多个值

Sql 基于同一表上的值在同一行上返回多个值,sql,oracle,pivot,Sql,Oracle,Pivot,我已经有一段时间被难住了,一直在尝试根据其他结果从我们的一个表中获取结果,并且每个值都不返回多行,这很难为我解释,所以我将给出一个示例 我们有一个价值观,例如苹果。每个苹果都有自己的序列号,serial。对于某些苹果,有多个(最多6个)序列值 ID APPLE SERIAL 2052 5035 1 2055 5035 4 2058 5035 8 2070 5040 5 在我的结果中,我想返回每

我已经有一段时间被难住了,一直在尝试根据其他结果从我们的一个表中获取结果,并且每个值都不返回多行,这很难为我解释,所以我将给出一个示例

我们有一个价值观,例如苹果。每个苹果都有自己的序列号,serial。对于某些苹果,有多个(最多6个)序列值

ID      APPLE       SERIAL
2052    5035        1
2055    5035        4
2058    5035        8
2070    5040        5
在我的结果中,我想返回每个苹果一次,以及分配给它的所有序列号,例如:

APPLE   SERIAL_1    SERIAL_2    SERIAL_3    SERIAL_4
5035    1           4           8
5040    5
我试着做了一个查询,它基本上连接了同一个表4次,说serial_x not in(其他serial)。这样做的问题是,它会产生如下多种结果:

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
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;

这显然是因为具有不同序列的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

你可以试试这个,它不雅致,但很管用:

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

您可以尝试使用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> 

您可以尝试使用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> 
甲骨文11g有一个功能,似乎可以满足您的需求。我这里没有11g,但下面应该很接近:

SELECT apple, listagg(serial, ',') WITHIN GROUP (ORDER BY serial) "Serial Numbers"
  FROM tbl
 GROUP BY apple;
您无法为每个序列项获得良好的列标题,但它应该可以工作。

Oracle11g具有的功能似乎可以满足您的需要。我这里没有11g,但下面应该很接近:

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

您无法为每个序列项获得良好的列标题,但它应该可以工作。

我会这样做:

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
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
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
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开始

这将产生以下输出:



游戏进行得有点晚,但由于在Oracle中没有使用PIVOT子句的答案,因此可能会很有趣

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

SQLFiddle示例:

游戏进行得有点晚,但由于在Oracle中没有使用PIVOT子句的答案,因此可能会很有趣

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


SQLFiddle示例:

在SQL Server上,您可以使用PIVOT函数。我不确定MySql和Oracle中是否存在PIVOT。Oracle中有PIVOT函数。在SQL Server上,您可以使用PIVOT函数。我不确定MySql和Oracle中是否存在PIVOT。Oracle中有PIVOT函数。@Marco我没有,但由于担心它不起作用,我只是尝试了一下,结果成功了。看看我在答案后面附加了什么。嘿,就像上面的解决方案一样,GROUP_CONCAT函数不适用于Oracle,同样,我应该在最初的帖子中说我正在使用Oracle。无论如何,应该有一个甲骨文的等价物,我会研究一下。谢谢:)@Jamie Joe是的[mysql]标签有误导性。我试图从问题中确定您使用的是MySQL还是Oracle,但无法确定。关于Oracle中的GROUP_CONCAT,也许可以提供帮助?它不起作用:OP希望每个序列都在不同的列中,而不是一列序列都已连接@Marco它正在工作,但是它没有将序列分成单独的列。我建议OP可以尝试在查询之外进行分离。。但我的答案似乎对OP没有多大用处,因为他需要Oracle的解决方案。@Marco我没有,但因为担心它不起作用,我只是尝试了一下,它起了作用。看看我在答案后面附加了什么。嘿,就像上面的解决方案一样,GROUP_CONCAT函数不适用于Oracle,同样,我应该在最初的帖子中说我正在使用Oracle。无论如何,应该有一个甲骨文的等价物,我会研究一下。谢谢:)@Jamie Joe是的[mysql]标签有误导性。我试图从问题中确定您使用的是MySQL还是Oracle,但无法确定。关于Oracle中的GROUP_CONCAT,也许可以提供帮助?它不起作用:OP希望每个序列都在不同的列中,而不是一列序列都已连接@Marco它正在工作,但是它没有将序列分成单独的列。我建议OP可以尝试在查询之外进行分离。。但我的答案对OP来说似乎不是很有用,因为他需要一个针对Oracle的解决方案。嘿,极限函数不适用于Oracle,也许我应该在我使用Oracle的帖子中提到。无论如何,我会用谷歌搜索到oracle的LIMIT。感谢您的快速回复@JamieJoe:你应该检查你的标签:如果你在使用Oracle,为什么要放MySql?嘿,LIMIT函数不适用于Oracle,也许我应该在帖子中提到我在使用Oracle。无论如何,我会用谷歌搜索到oracle的LIMIT。感谢您的快速回复@JamieJoe:你应该检查一下你的标签:如果你在使用Oracle,为什么要放MySql?太好了,正是我需要的。非常感谢你!现在是学习代码的时候了:)太好了,正是我所需要的。非常感谢你!现在是学习代码的时候了:)