Sql 比较具有相同键的两行并确定值是否不同

Sql 比较具有相同键的两行并确定值是否不同,sql,oracle,Sql,Oracle,我有一张这样的桌子: + -------------+------------+------+-----------+-----------+ | M_PACK_INTID | M_PACK_REF | M_NB | M_XPFWSPT | M_BPFOLIO | + -------------+------------+------+-----------+-----------+ | 1.781 | 100 | 101 | 12 | PFOLIO

我有一张这样的桌子:

+ -------------+------------+------+-----------+-----------+ | M_PACK_INTID | M_PACK_REF | M_NB | M_XPFWSPT | M_BPFOLIO | + -------------+------------+------+-----------+-----------+ | 1.781 | 100 | 101 | 12 | PFOLIO | | 1.781 | 100 | 102 | 12 | PFOLIO | | 1.781 | 100 | 103 | 12 | PFOLIO | | 1.781 | 100 | 104 | 12.3 | PFOLIO | | 1.781 | 200 | 201 | 15 | PFOLIO | | 1.781 | 200 | 202 | 15 | PFOLIO | | 1.781 | 200 | 203 | 15 | PFOLIO | | 1.781 | 200 | 204 | 15 | PFOLIO | + -------------+------------+------+-----------+-----------+
M_PACK_REF
100
400
我试图从该表中提取每个M_PACK_REF的第一行和最后一行,并计算不同的M_XPFWSPT的发生率:

select M_PACK_REF
 from 
 (
    select M_PACK_REF, M_NB, M_XPFWSPT
    from GATHER
    where M_NB = (select min(M_NB) from GATHER G where G.M_PACK_REF = GATHER.M_PACK_REF)
    or M_NB = (select max(M_NB) from GATHER G where G.M_PACK_REF = GATHER.M_PACK_REF)
 )
 group by M_PACK_REF, M_NB, M_XPFWSPT
 having count (distinct M_XPFWSPT) > 1;
。。。但它给了我一张空桌子。
有人能帮忙吗

首先对行进行编号,因此获得每个M_PACK_REF的第一行和第四行。然后进行比较

with numbered as
(
  select
    m_pack_ref,
    m_nb,
    m_xpfwspt,
    row_number() over (partition by m_pack_ref order by m_nb) as rn
  from gather
)
select *
from (select * from numbered where rn = 1) first
join (select * from numbered where rn = 4) fourth
  on  fourth.m_pack_ref = first.m_pack_ref
  and fourth.m_xpfwspt <> first.m_xpfwspt;

首先给你的行编号,所以得到每个M_PACK_REF的第一行和第四行。然后比较

with numbered as
(
  select
    m_pack_ref,
    m_nb,
    m_xpfwspt,
    row_number() over (partition by m_pack_ref order by m_nb) as rn
  from gather
)
select *
from (select * from numbered where rn = 1) first
join (select * from numbered where rn = 4) fourth
  on  fourth.m_pack_ref = first.m_pack_ref
  and fourth.m_xpfwspt <> first.m_xpfwspt;

如果我理解正确的话,你就可以使用存在,并且必须去做

select M_PACK_REF, M_NB, M_XPFWSPT
from GATHER g1
WHERE exists (
  SELECT 1 
  FROM GATHER g2
  HAVING
      min(g2.M_NB) = g1.M_NB OR MAX(g2.M_NB) = g1.M_NB 
  and 
      COUNT(distinct M_XPFWSPT) > 1
)

如果我理解正确的话,你就可以使用存在,并且必须去做

select M_PACK_REF, M_NB, M_XPFWSPT
from GATHER g1
WHERE exists (
  SELECT 1 
  FROM GATHER g2
  HAVING
      min(g2.M_NB) = g1.M_NB OR MAX(g2.M_NB) = g1.M_NB 
  and 
      COUNT(distinct M_XPFWSPT) > 1
)
你能试试这个吗

WITH filtered as 
(
SELECT 
    M_PACK_REF,
    M_XPFWSPT,
    COUNT(*) as Cnt
FROM GATHER
    WHERE M_NB like '%01' or M_NB like '%04'
GROUP BY M_PACK_REF, M_XPFWSPT
HAVING COUNT(*) = 1
)

SELECT DISTINCT M_PACK_REF FROM filtered
如果M_XPFWSPT的值不同,则每对M_PACK_REF,M_XPFWSPT将有一行。如果M_XPFWSPT the same-count*将返回2,您能试试这个吗

WITH filtered as 
(
SELECT 
    M_PACK_REF,
    M_XPFWSPT,
    COUNT(*) as Cnt
FROM GATHER
    WHERE M_NB like '%01' or M_NB like '%04'
GROUP BY M_PACK_REF, M_XPFWSPT
HAVING COUNT(*) = 1
)

SELECT DISTINCT M_PACK_REF FROM filtered

如果M_XPFWSPT的值不同,则每对M_PACK_REF,M_XPFWSPT将有一行。如果M_XPFWSPT the same-count*将返回2

您确定在M_PACK_REF、M_NB、M_XPFWSPT上分组是您想要的吗?您的示例中没有歧义您期望的结果是什么?这里的大多数人想要格式化的文本,而不是图像。@D-Shih我对问题进行了编辑以使其更清晰。我已将图像替换为文本,因为这是显示示例数据的首选方式。您确定在M_PACK_REF、M_NB、M_XPFWSPT上分组是您想要的吗?您的示例中没有重复,您期望的结果是什么?这里的大多数人想要格式化的文本,而不是图像。@D-Shih我对问题进行了编辑以使其更清晰。我将图像替换为文本,因为这是显示示例数据的首选方式。非常感谢Thorsten!你在你的加入下输入了一个错误,我正在编辑它:非常感谢Thorsten!你在你的加入下输入了一个错误,我正在编辑它:谢谢D-Shih,这个查询的问题是它只选择最高和最低的m_-PACK_-REF,而不是中间可能存在的所有其他m_-PACK_-REF:谢谢D-Shih,这个查询的问题是它只选择最高和最低的m_-PACK_-REF,但并非所有可能存在于两者之间的其他因素: