【问题标题】:how to compare multiple rows in where clause如何比较where子句中的多行
【发布时间】:2017-03-03 10:48:43
【问题描述】:
Given table:

create table borrower (
customer_number char ( 1 0 ) ,
loan_number char ( 1 0 ));

问题:查找共享客户“1234”拥有的所有贷款的每个客户的客户编号(即 ID)。如果客户编号为“1234”的客户有贷款“L1”和“L2”,则需要找到所有共享“L1”和“L2”的客户(包括客户“1234”)。

我在表中创建了 4 个条目,列 (customer_number, loan_number) 是 (1234, L1) (1234, L2) (1, LI)(1, L2)(2, L1)。我正在使用查询

select distinct customer_number 
from borrower
where loan_number IN(
    select loan_number 
    from borrower 
    where customer_number='1234'

但它正在检索输出,例如

1234, 1, 2 

我的输出中只需要 1 和 1234(Customer_number),因为它是唯一一个同时具有贷款编号 L1 和 L2 的。 Cutsomer_number "2" 不与两个loan_number 相关联,因此它应该出现在输出中。

我也试过用“all”代替“IN”。

select distinct customer_number 
    from borrower
    where loan_number= all(
        select loan_number 
        from borrower 
        where customer_number='1234'

输出:没有

【问题讨论】:

  • Query using "IN" id select customer_number from borrower where loan_number IN (select loan_number from borrower where customer_number='1234') 此查询生成输出 1234、1234、1、1
  • 在此期间我正在尝试寻找解决方案,您可以将您的示例数据放入rextester.com/l/mysql_online_compiler 以便其他人尝试。还可以编辑您的问题并在上述链接中使用更新的表格结构分享 URL
  • Query using "all" id select customer_number from borrower where loan_number = all (select loan_number from borrower where customer_number='1234') 此查询未检索到任何输出
  • @Hogan 我已经更新了这个问题。请再读一遍。
  • @user3827844 -- 啊,谢谢。现在这个问题说得通了。

标签: mysql sql database postgresql


【解决方案1】:

编辑:根据 OP 的说明

SELECT customer_number
FROM borrower b1
    WHERE b1.loan_number IN
    (SELECT loan_number FROM borrower
     WHERE customer_number=1234
     )
GROUP BY customer_number
HAVING count(*)=
  (SELECT count(*)
   FROM borrower
   WHERE customer_number=1234)

解释:首先我计算给定 customer_number 的贷款数量。在这种情况下,它应该是2。现在我将此计数与计数相同的每组 customer_number 进行比较。

【讨论】:

  • 我也可以使用“distinct”来抑制行,但我想要同时拥有贷款 L1 和 L2 而不是 L1 或 L2 的客户编号。您给出的查询也检索了只有 L1 loan_number 的行。
  • 您的样本数据没有这样的情况。再举几个例子
  • 更多表条目就像列 (customer_number, loan_number) 是 (1234, L1) (1234, L2) (1, LI)(1, L2) (2, L1) 。在此 (2, L1) 中,表中的新行条目仅与 L1 贷款相关联,但与 L2 无关。所以这个条目不应该被检索。只有与 loan_number(L1 和 L2)关联的 customer_number 才能检索。
  • 是的,它正在工作......但我不明白你为什么使用 GROUP BY customer_number HAVING count()= (SELECT count() FROM borrower WHERE customer_number=第1234章,你能解释一下吗?
  • 获取2的计数为1234。如果 1234 有 3 笔贷款,查询仍然有效。我在答案中添加了解释。
【解决方案2】:

您可以使用临时表和连接。

/* create a table of the loans we are looking for */
create table Temp select distinct loan_number from Borrower 
where customer_number = '1234';

/* join against the temp table and select borrowers with 3 matches */
select customer_number as 'Match' 
from (select customer_number, COUNT(*) as C 
         from Borrower 
         inner join Temp on Borrower.loan_number = Temp.loan_number
         group by customer_number) X
where C = 3

【讨论】:

  • 但是对于大量的行比如 20000 或 50000,创建临时表可能效率低下
  • 是的,这是真的。使用带有loan_number 索引的中间表会有所帮助。编辑:临时表中可能不会有很多贷款,所以连接应该非常有效。
  • 你能提交你对上述陈述的答案吗?
  • 由于我们是在loan_number 上加入的,所以在Borrower 表中的该列上放置一个索引将有助于加入,例如索引 ix_borrower_loan_number(loan_number)。
【解决方案3】:

你确定你执行了所有的sql语句吗?看起来还可以:

select distinct customer_number 
from borrower
where 
  loan_number IN(
    select a.loan_number from borrower a where a.customer_number='1234'
  )

【讨论】:

  • 这不是答案,这是评论。
  • select distinct customer_number from borrower where loan_number IN(select a.loan_number from borrower a where a.customer_number='1234') 正在运行但没有检索到所需的输出,但现在我有了处理方法它
【解决方案4】:

我认为您只需要同时拥有 L1 和 L2 贷款的 customer_number。所以你试试这个代码为你的表

查询 -

SELECT customer_number
FROM
  (SELECT customer_number,
          loan_number
   FROM borrower
   WHERE loan_number IN (SELECT loan_number FROM borrower
 WHERE customer_number=1234)
   GROUP BY loan_number,
            customer_number)t
GROUP BY customer_number
HAVING count(*) =
  (SELECT count(*)
   FROM borrower
   WHERE customer_number=1234)

如果未提及客户编号。但我们需要一个客户列表,他们都适用于 L1 和 L2 等所有贷款

查询2 -


SELECT customer_number
FROM
  (SELECT customer_number,
          loan_number
   FROM borrower
   WHERE loan_number IN (SELECT distinct(loan_number) FROM borrower)
   GROUP BY loan_number,
            customer_number)t
GROUP BY customer_number
HAVING count(*) =
  (SELECT count(distinct(loan_number)) FROM borrower)

Query2 说明

SELECT distinct(loan_number) FROM borrower

loan_number
L1
L2 

上述查询用于从借方表中查找唯一的贷款。

SELECT customer_number, loan_number FROM borrower
   WHERE loan_number IN (SELECT loan_number FROM borrower
 WHERE customer_number=1234)
   GROUP BY loan_number, customer_number
customer_number 贷款编号
1 L1
第1234章
2 L1
1 L2
第1234章

上述查询用于查找所有拥有贷款分组的客户。

SELECT count(distinct(loan_number)) FROM借款人

上面的代码给出了计数 2 作为输出。(即 L1 和 L2)。在查询中拥有 count(*) 将检查 customer_number 将出现多少次。在此示例中,它会打印在表格中出现两次的 customer_number。

最后 Query2 显示类似的输出

1
第1234章

最终输出删除 customer_number 2,因为他只有“L1”。用户 1 和 1234 都有贷款“L1”和“L2”

希望此代码对您有所帮助。

【讨论】:

  • 应尽可能避免硬编码。这里2 不固定。他只是举了一个例子,在实际情况下,可能不止这些。因此,您不应从硬编码中获取2,而应使用子查询来提供此计数。检查我的答案。
  • 感谢您的建议@Utsav。我更新了我的代码。
  • 改为使用SELECT count(*) FROM borrower WHERE customer_number=1234 获取仅需要的客户的贷款计数
  • @Sahathulla 你还在使用硬静态值(L1 L2)
  • @user3827844 现在根据您给定的用户 1234 更新
【解决方案5】:

我有另一个查询来检索所需的行,由于 EXCEPT,此查询在 MySQL 中可能不起作用

Select customer_number from borrower as b
where not exists
   (select loan_number from borrower where customer_number='1234')
except
   (select loan_number from borrower where customer_number=b.customer_number)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-26
    • 1970-01-01
    • 1970-01-01
    • 2017-09-16
    • 1970-01-01
    • 2019-03-28
    • 2022-11-15
    相关资源
    最近更新 更多