【问题标题】:Sql join only 1 rowsql只加入1行
【发布时间】:2020-10-26 19:29:05
【问题描述】:

我想根据 ViewPriority 加入来自 AgreementRoleGroup 的只有一行的 CustomerAgreementRole 表。示例:CustomerAgreementRole 可以有三行。我只想要 ViewPriority 最高的连接行

AgreementId, AgreementRoleId 
1            1
1            2
1            3  

CustomerAgreementRole

 1. AgreementId
 2. AgreementRoleId

AgreementRoleGroup

 1. AgreementRoleId
 2. ViewPriority

当前查询:

select * from CustomerAgreementRole car 
join (select agreementRoleId, min(ViewPriority) as mi from AgreementRoleGroup group by AgreementRoleId) as arg on car.AgreementRoleId = arg.AgreementRoleId

预期结果:

AgreementId, AgreementRoleId, ViewPriority
1            1                1

【问题讨论】:

  • 您能否展示您当前的查询或尝试以及预期结果
  • 你们有没有发现 GL 和 GMB 是商业伙伴,可以互相扣分,但不能互相扣分?
  • 附带说明:SQL 中的名称通常不区分大小写。因此,当格式不同时(customeragreementroleCUSTOMERAGREEMENTROLE ),像 CustomerAgreementRole 这样的长名称会变得不那么可读。因此,无论大小写格式如何,通常都使用下划线来确保可读性 (customer_agreement_role)。
  • 请提供样本数据和预期结果

标签: sql tsql


【解决方案1】:

可能是这样的:

 SELECT *
 FROM CustomerAgreementRole A
 CROSS APPLY
 (
    SELECT TOP 1 *
    FROM AgreementRoleGroup B
    WHERE A.[AgreementRoleId] = B.[AgreementRoleId]
    ORDER BY ViewPriority DESC
 ) C

【讨论】:

  • 我试过查询。它返回所有三行,而不是我想要的那一行
【解决方案2】:

由于 AgreementRoleGroup 已经获得了 AgreementRoleId,我们可以通过一些子查询来 join

select a.*, b2.ViewPriority from CustomerAgreementRole a left join 
(
  select b.AgreementRoleId, b.ViewPriority 
  from AgreementRoleGroup b 
  where b.ViewPriority = 
  (
    select min(ViewPriority) 
    from AgreementRoleGroup
  )
) b2
on a.AgreementRoleId=b2.AgreementRoleId

但我会说使用min() 不是最好的方法,你应该在@gotqn 答案中使用top 但现在这可以工作。

重新编辑

create table CustomerAgreementRole (AgreementId int,AgreementRoleId int);
insert into CustomerAgreementRole values (1,1);
insert into CustomerAgreementRole values (2,3);
insert into CustomerAgreementRole values (3,4);
insert into CustomerAgreementRole values (4,2);

create table AgreementRoleGroup (AgreementRoleId int, ViewPriority int);
insert into AgreementRoleGroup values (1,3);
insert into AgreementRoleGroup values (3,4);
insert into AgreementRoleGroup values (4,2);
insert into AgreementRoleGroup values (2,1);

我使用这些作为样本数据并得到了这个结果db<>fiddle

如果您只想要那一行而不关心 ViewPriority 需要最小,请改用top

select top 1 a.*, b.ViewPriority from CustomerAgreementRole a left join 
AgreementRoleGroup b
on a.AgreementRoleId=b.AgreementRoleId
order by ViewPriority asc

【讨论】:

  • 是的,我只是再次编辑,因为意识到某些变量是未命中类型。我在测试时使用 a 和 b 作为你的表。
  • 它现在给了我所有三行,但其中任何一个都没有 viewPriority
  • @Sindresvends 使用一些在线数据库模拟器和结果重新编辑,可能是因为您的表 AgreementRoleGroup 以不同的方式存储数据。
  • 更改了 CustomerAgreementRole 的输入数据,因为我有几行具有相同的 agreementId 和不同的 agremeentRoles。我只想要与最低 viewPriority 匹配的一行。在我的数据库中,我得到了所有行,但没有人拥有 viewPriority。 dbfiddle.uk/…
  • 您的示例已经获得了具有 ViewPriority 的那一行,如果您只想要具有 ViewPriority 的那一行,我会编辑一些代码,但是既然您说您的数据库根本没有 ViewPriority,那么问题不在于代码.是你的数据。
【解决方案3】:

对于每个 AgreementId,您需要具有最高优先级(最低 ViewPriority 值)的 AgreementRoleId。这意味着您想要对 CustomerAgreementRole 行进行排名,并且只显示排名最高的行。在 SQL 中,排名通常使用ROW_NUMBERRANKDENSE_RANK 完成。

select AgreementId, AgreementRoleId, ViewPriority
from
(
  select
    car.AgreementId, car.AgreementRoleId, arg.ViewPriority,
    row_number() over (partition by car.AgreementId order by arg.ViewPriority) as rn
  from CustomerAgreementRole car
  join AgreementRoleGroup arg on arg.AgreementRoleId = car.AgreementRoleId
) ranked
where rn = 1;

【讨论】:

    【解决方案4】:

    让它与这个一起工作:

    WITH CTEViewPriority (lowestViewPriority, agreementId) as (
        select min(ViewPriority), AgreementId from CustomerAgreementRole as car 
        left join AgreementRoleGroup arg on car.AgreementRoleId = arg.AgreementRoleId
        group by agreementId
        )
    select * from CustomerAgreementRole as car
    inner join CTEViewPriority as arg on lowestViewPriority = arg.agreementRoleId and arg.agreementId = car.agreementId
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-13
      • 2018-01-18
      • 1970-01-01
      相关资源
      最近更新 更多