Sql 如果列数据不同,则获取组的行

Sql 如果列数据不同,则获取组的行,sql,oracle,oracle11g,oracle12c,Sql,Oracle,Oracle11g,Oracle12c,在查询的最后一步中,我遇到了一个问题,那就是选择一组行中的所有行,这些行的混合值为一个名为National的列 我曾尝试为国籍列指定一个数字表示形式,对于X为1,对于其他国籍为0,然后对组使用MINMAX,但仍然无法找到一种方法来获取组中具有该性质数据的所有行 查看下面的示例以获取说明: GROUP_ID VALUE_1 VALUE_2 ..... VALUE_N NATIONALITY ----------------------------------------------

在查询的最后一步中,我遇到了一个问题,那就是选择一组行中的所有行,这些行的混合值为一个名为National的列

我曾尝试为国籍列指定一个数字表示形式,对于X为1,对于其他国籍为0,然后对组使用
MIN
MAX
,但仍然无法找到一种方法来获取组中具有该性质数据的所有行

查看下面的示例以获取说明:

GROUP_ID    VALUE_1    VALUE_2 ..... VALUE_N   NATIONALITY
------------------------------------------------------------
  1           282       8383           383         X
  1           737        722           712         Y
  1           273       7123           123         Y

  2           347        234           235         X
  2          8723        274           474         Y

  3           747         23           623         X

  4           133       1823           612         Y
  4           747        533           100         Y

  5           343       2383           213         X
  5           333        123           711         X
  5           312        344           766         X
  5           456       6003           190         Y
GROUP_ID    VALUE_1    VALUE_2 ..... VALUE_N   NATIONALITY
------------------------------------------------------------
  1           282       8383           383         X
  1           737        722           712         Y
  1           273       7123           123         Y

  2           347        234           235         X
  2          8723        274           474         Y

  5           343       2383           213         X
  5           333        123           711         X
  5           312        344           766         X
  5           456       6003           190         Y
已排序的数据和已处理的数据如下所示:

GROUP_ID    VALUE_1    VALUE_2 ..... VALUE_N   NATIONALITY
------------------------------------------------------------
  1           282       8383           383         X
  1           737        722           712         Y
  1           273       7123           123         Y

  2           347        234           235         X
  2          8723        274           474         Y

  3           747         23           623         X

  4           133       1823           612         Y
  4           747        533           100         Y

  5           343       2383           213         X
  5           333        123           711         X
  5           312        344           766         X
  5           456       6003           190         Y
GROUP_ID    VALUE_1    VALUE_2 ..... VALUE_N   NATIONALITY
------------------------------------------------------------
  1           282       8383           383         X
  1           737        722           712         Y
  1           273       7123           123         Y

  2           347        234           235         X
  2          8723        274           474         Y

  5           343       2383           213         X
  5           333        123           711         X
  5           312        344           766         X
  5           456       6003           190         Y
目标结果:

GROUP_ID    VALUE_1    VALUE_2 ..... VALUE_N   NATIONALITY
------------------------------------------------------------
  1           282       8383           383         X
  1           737        722           712         Y
  1           273       7123           123         Y

  2           347        234           235         X
  2          8723        274           474         Y

  3           747         23           623         X

  4           133       1823           612         Y
  4           747        533           100         Y

  5           343       2383           213         X
  5           333        123           711         X
  5           312        344           766         X
  5           456       6003           190         Y
GROUP_ID    VALUE_1    VALUE_2 ..... VALUE_N   NATIONALITY
------------------------------------------------------------
  1           282       8383           383         X
  1           737        722           712         Y
  1           273       7123           123         Y

  2           347        234           235         X
  2          8723        274           474         Y

  5           343       2383           213         X
  5           333        123           711         X
  5           312        344           766         X
  5           456       6003           190         Y
我正在尝试选择组中同时具有X(s)Y(s)的所有行


有谁能给我一个如何解决这个问题的提示吗?我真的不知道从哪里开始,分析函数没有用,
LEAD
函数没有为我服务,因为每个组中的行数不是固定的,所以前导行可以有值X,但组中它后面的一个是Y,所以在这种情况下将忽略该组,在我的情况下,这是错误的。

这里的一种方法是计算每个群体出现的不同国籍的数量,然后只保留那些拥有一个以上不同国籍的群体

SELECT
    t.GROUP_ID,
    t.VALUE_1,
    t.VALUE_2,
    ...,
    t.VALUE_N,
    t.NATIONALITY
FROM
(
    SELECT *,
           COUNT(DISTINCT NATIONALITY) OVER (PARTITION BY GROUP_ID) distinct_count
    FROM yourTable
) t
WHERE t.distinct_count > 1

当然,此查询将任何两个不同的国籍计算为对结果集有效。如果您确实需要显式检查X和Y,我们可以修改此查询。

这里的一种方法是统计每个组出现的不同国籍的数量,然后只保留具有多个不同国籍的组

SELECT
    t.GROUP_ID,
    t.VALUE_1,
    t.VALUE_2,
    ...,
    t.VALUE_N,
    t.NATIONALITY
FROM
(
    SELECT *,
           COUNT(DISTINCT NATIONALITY) OVER (PARTITION BY GROUP_ID) distinct_count
    FROM yourTable
) t
WHERE t.distinct_count > 1
当然,此查询将任何两个不同的国籍计算为对结果集有效。如果确实需要显式检查X和Y,我们可以修改此查询

我正在尝试选择同时具有X(s)和Y(s)的组中的所有行

使用带有
CASE
语句的
COUNT(…)OVER(PARTITION BY…
分析函数将计数限制为分区内的
X
s或
Y
s:

SELECT *
FROM   (
  SELECT t.*,
         COUNT( CASE nationality WHEN 'X' THEN 1 END )
            OVER ( PARTITION BY group_id ) AS x,
         COUNT( CASE nationality WHEN 'y' THEN 1 END )
            OVER ( PARTITION BY group_id ) AS y
  FROM   your_table t
)
WHERE  x > 0 AND y > 0
我正在尝试选择同时具有X(s)和Y(s)的组中的所有行

使用带有
CASE
语句的
COUNT(…)OVER(PARTITION BY…
分析函数将计数限制为分区内的
X
s或
Y
s:

SELECT *
FROM   (
  SELECT t.*,
         COUNT( CASE nationality WHEN 'X' THEN 1 END )
            OVER ( PARTITION BY group_id ) AS x,
         COUNT( CASE nationality WHEN 'y' THEN 1 END )
            OVER ( PARTITION BY group_id ) AS y
  FROM   your_table t
)
WHERE  x > 0 AND y > 0

在Oracle 12c中,
MATCH\u RECOGNIZE
子句可以非常快速、清晰地解决此问题

with
     test_data ( group_id, value_1, value_2, value_n, nationality ) as (
       select 1,  282, 8383, 383, 'X' from dual union all
       select 1,  737,  722, 712, 'Y' from dual union all
       select 1,  273, 7123, 123, 'Y' from dual union all
       select 2,  347,  234, 235, 'X' from dual union all
       select 2, 8723,  274, 474, 'Y' from dual union all
       select 3,  747,   23, 623, 'X' from dual union all
       select 4,  133, 1823, 612, 'Y' from dual union all
       select 4,  747,  533, 100, 'Y' from dual union all
       select 5,  343, 2383, 213, 'X' from dual union all
       select 5,  333,  123, 711, 'X' from dual union all
       select 5,  312,  344, 766, 'X' from dual union all
       select 5,  456, 6003, 190, 'Y' from dual
     )
-- End of test data (not part of the solution). SQL query begins BELOW THIS LINE.
select *
from   test_data
match_recognize (
  partition by group_id
  all rows per match
  pattern ( a*? ( x a*? y | y a*? x ) a* )
  define  x as nationality = 'X',
          y as nationality = 'Y'
)
;
输出

GROUP_ID    VALUE_1    VALUE_2    VALUE_N  NATIONALITY
--------  ---------  ---------  ---------  -----------
       1        282       8383        383  X
       1        737        722        712  Y
       1        273       7123        123  Y
       2        347        234        235  X
       2       8723        274        474  Y
       5        343       2383        213  X
       5        333        123        711  X
       5        312        344        766  X
       5        456       6003        190  Y

9 rows selected.

在Oracle 12c中,
MATCH\u RECOGNIZE
子句可以非常快速、清晰地解决此问题

with
     test_data ( group_id, value_1, value_2, value_n, nationality ) as (
       select 1,  282, 8383, 383, 'X' from dual union all
       select 1,  737,  722, 712, 'Y' from dual union all
       select 1,  273, 7123, 123, 'Y' from dual union all
       select 2,  347,  234, 235, 'X' from dual union all
       select 2, 8723,  274, 474, 'Y' from dual union all
       select 3,  747,   23, 623, 'X' from dual union all
       select 4,  133, 1823, 612, 'Y' from dual union all
       select 4,  747,  533, 100, 'Y' from dual union all
       select 5,  343, 2383, 213, 'X' from dual union all
       select 5,  333,  123, 711, 'X' from dual union all
       select 5,  312,  344, 766, 'X' from dual union all
       select 5,  456, 6003, 190, 'Y' from dual
     )
-- End of test data (not part of the solution). SQL query begins BELOW THIS LINE.
select *
from   test_data
match_recognize (
  partition by group_id
  all rows per match
  pattern ( a*? ( x a*? y | y a*? x ) a* )
  define  x as nationality = 'X',
          y as nationality = 'Y'
)
;
输出

GROUP_ID    VALUE_1    VALUE_2    VALUE_N  NATIONALITY
--------  ---------  ---------  ---------  -----------
       1        282       8383        383  X
       1        737        722        712  Y
       1        273       7123        123  Y
       2        347        234        235  X
       2       8723        274        474  Y
       5        343       2383        213  X
       5        333        123        711  X
       5        312        344        766  X
       5        456       6003        190  Y

9 rows selected.

能否显示当前使用的查询。可能需要/调整一些小问题。您能否显示当前使用的查询。可能需要/调整一些小的东西。谢谢,它起作用了,这对我很有帮助,无需修改,除非你想以此作为公众的榜样benefit@simsimMT0给出的答案是,如果你真的需要计算X和Y,我会使用它。但我只会在必要时这样做。我在我的主要查询中已经这样做了,我给了我的目标国籍一个“X”值,其他任何一个都给了“Y”值。我的答案应该适合你的数据。如果你真的需要检查每封信,请使用另一个答案。谢谢,它很有效,这对我很有帮助,无需修改,除非你想以此作为公众的榜样benefit@simsimMT0给出的答案是,如果你真的需要计算X和Y,我会使用它。但我只会在必要时这样做。我在我的主要查询中已经这样做了,我给了我的目标国籍一个“X”值,其他任何一个都给了“Y”值。我的答案应该适合你的数据。如果你真的需要检查每个字母,请使用另一个答案。