【问题标题】:Select from multiple tables with OR condtions从具有 OR 条件的多个表中选择
【发布时间】:2016-01-29 21:03:20
【问题描述】:

我正在使用 SQL Server,但我很难从我想要的 SELECT 查询中获取结果。我必须从下面给出的 3 个表中选择记录:

客户(客户 ID、姓名、年龄、出生日期)

地址(clientID, city, street)

电话(ClientID、personalPhone、officePhone、homePhone)

在我的输入中,我可以有 (dateOfBirth, steet, homePhone) 并且我需要 Disntinct ClientIDs 结果。这些输入值是可选的。并非强制每次所有这些输入值都具有值,在某些情况下仅提供街道和家庭电话,或者有时仅提供街道。

参数中有“或”关系!就像我通过 homePhone 一样,即使记录也应该返回。

【问题讨论】:

  • 您当前的 SELECT 语句是什么样的?
  • I'm using SQL Server - 那么为什么要使用 MySQL 和 Oracle 标签?
  • SELECT clientID FROM CLIENT.CLIENT where dateOfBirth = :dateOfBirth intersect SELECT clientID FROM CLIENT.Address where steet= :street intersect SELECT clientID FROM client.Phone where homePhone= :homePhone
  • 请阅读stackoverflow.com/help/how-to-ask这里是START的好地方
  • 我们的示例代码有一个变量的冒号前缀似乎很奇怪——你真的在使用 sql-server 吗?

标签: sql sql-server


【解决方案1】:

这与 Mureinik 的答案几乎相同,但他没有使用左外连接,因此如果您的客户有地址但没有电话号码,除非您使用外连接:

SELECT DISTINCT client_id
FROM   client c
LEFT OUTER JOIN   address a 
    ON c.client_id = a.client_id
LEFT OUTER JOIN   phone p 
    ON c.client_id = p.client_id
WHERE  (@date_of_birth IS NULL OR c.date_of_birth = @date_of_birth) AND
       (@street IS NULL OR @street = a.street) AND
       (@home_phone IS NULL OR @home_phone = p.home_phone)

【讨论】:

  • 它没有用,我只输入 home_phone 进行了测试,当这个 home_phone 的电话表中实际存在记录时没有返回记录:(
  • 如果用户不包含这些值,您是否传递空值 - 或者您只是传递空字符串?您想确保它们为空 - 否则您必须将条件逻辑更改为 (@date_of_birth = '' OR c.date_of_birth = @date_of_birth)。但是发送空值。比检查空字符串要好得多。
  • 周末离开。如果仍未解决,我将在星期一标记此问题和答案。
  • @user3077985 我重新访问了这个以提供帮助,但你还没有回答这个问题。我假设你已经明白了。
【解决方案2】:

您可以使用or 条件短路逻辑。假设您用@ 表示参数:

SELECT    DISTINCT client_id
FROM      client c
LEFT JOIN address a ON c.client_id = a.client_id
LEFT JOIN phone p ON c.client_id = p.client_id
WHERE     (@date_of_birth IS NULL OR c.date_of_birth = @date_of_birth) AND
          (@street IS NULL OR @street = a.street) AND
          (@home_phone IS NULL OR @home_phone = p.home_phone)

【讨论】:

  • 您应该使用左外连接,因为您的查询将排除缺少地址或电话号码的记录。鉴于帖子中的信息有限,我们不知道插入客户记录是否需要电话号码和地址。
  • 客户表中可能有一些记录,其 clientID 没有地址或电话号码表中的记录。
【解决方案3】:

将 null 默认设置为“all”或通配符的标准方式如下:

SELECT *
FROM client c
LEFT JOIN address a ON c.client_id = a.client_id
LEFT JOIN phone p ON c.client_id = p.client_id
WHERE (COALESCE(@date_of_birth,c.date_of_birth) = c.date_of_birth 
    OR COALESCE(@street,c. a.street) =  a.street
    OR COALESCE(@home_phone,p.home_phone) = p.home_phone )
 -- Put the following line in if you want at least one parameter to not be null
 AND COALESCE(@date_of_birth,@street,@home_phone) is not null

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多