【问题标题】:how to select data from multiple table with variable condition | MySQL如何从具有可变条件的多个表中选择数据| MySQL
【发布时间】:2018-11-03 13:45:04
【问题描述】:

我在数据库中有两个表来存储客户基本信息(姓名、位置、电话号码)和另一个表来存储与客户相关的交易(date_sub、profile_sub、isPaid、date_exp、client_id),我有一个 html 表要查看客户基本信息和交易(如果可用),我的问题是我无法同时从表 internetClientinternetclientDetails 中选择客户信息,因为只有当客户端在明细表中有 trans 时才会产生查询。两个表字段如下:

internetClient

--------------------------------------------------------
id         full_name       location    phone_number
-------------------------------------------------------
4         Joe Amine         beirut       03776132
5         Mariam zoue       beirut       03556133

internetclientdetails 

--------------------------------------------------------------------------
incdid   icid      date_sub      date_exp      isPaid      sub_price
----------------------------------------------------------------------------
  6        4      2018-01-01     2018-01-30      0           2000
  7        5      2017-01-01     2017-01-30      0           1000
  8        4      2018-03-01     2018-03-30      1           50000
  9        5      2018-05-01     2019-05-30      1           90000

// incdid > internetClientDetailsId
// icid> internetClientId

如果客户端有trans in orderdetails,查询应该返回如下值:

    client_id    full_name           date_sub     date_exp      isPaid    sub_price
-------------------------------------------------------------------------------------
       4          Joe Amine          2018-03-01     2018-03-30      1           50000
       5           Mariam zoue       2018-05-01     2019-05-30      1           90000

否则,如果客户端在 internetOrederDetails

中没有 id
    --------------------------------------------------------
    icid      full_name       location    phone_number
    -------------------------------------------------------
    4         Joe Amine         beirut       03776132
    5         Mariam zoue       beirut       0355613

提前致谢

【问题讨论】:

  • 你只想INNER JOIN两张表吗?还是分别返回它们,但在与数据库的一次事务中返回?
  • 只需加入并在哪里可以得到。
  • @MatBailie 我想要的是获取最新订阅日期以及 sub_price 和其他详细信息的客户基本信息。我更新了问题以显示所需的结果
  • 什么版本的mySQL?可能会使用分析函数
  • Nope 8.0 does 但是我们可以使用派生表来模拟它。

标签: mysql sql database select join


【解决方案1】:

尝试左连接。它将显示来自 internetClient 的所有记录和来自 internetclientdetails 的相关记录

Select internetClient.id, internetClient.full_name
     , internetClient.location, internetClient.phone_number
     , internetclientdetails.incdid, internetclientdetails.icid
     , internetclientdetails.date_sub, internetclientdetails.date_exp
     , internetclientdetails.isPaid, internetclientdetails.sub_price 
from internetClient 
left join internetclientdetails 
  on internetClient.id=internetclientdetails.icid group by internetclientdetails.icid order by internetclientdetails.incdid desc

如果你想获取记录,只有付费客户,那么你可以试试下面的

Select internetClient.id, internetClient.full_name
     , internetClient.location, internetClient.phone_number
     , internetclientdetails.icid, internetclientdetails.incdid
     , internetclientdetails.date_sub, internetclientdetails.date_exp
     , internetclientdetails.isPaid, internetclientdetails.sub_price 
from internetClient 
left join internetclientdetails 
  on internetClient.id=internetclientdetails.icid 
 and internetclientdetails.isPaid=1 group by internetclientdetails.icid
order by internetclientdetails.incdid desc

【讨论】:

  • 这工作正常,但不是我想要的,因为这是获取同一客户的所有记录,我需要的是选择具有 internetClient 中所有详细信息的客户,并且只有internetclientDetails中的最后一条记录,如果internetClientDetails中没有记录,则只获取internetClient中的记录,这是基本信息。提前致谢
  • 我已经更新了代码。检查它是否有效。我已按 desc 添加订单
  • 仍然在记录中重复:/,您的查询选择同一客户端的所有记录,而这意味着如果存在于 internetclientdetails 中并且如果存在相关数据,则只为每个客户端返回一条记录以及相关数据不仅从internetclient 获得基本信息,非常感谢您的努力,这正在停止我的工作流程:S
【解决方案2】:

摘要

我们生成一个仅包含 ICID 和 max(date_sub)(别名:ICDi)的数据集,我们将其连接到 InternetClientDetails (ICD) 以获得每个客户端的最大日期记录。然后把这个加入IC记录;确保我们保留所有 InternetClient(IC) 记录;并且只显示相关的最大详细记录。

以下方法应该适用于大多数 mySQL 版本。它不使用我们可以用来获取最大日期的分析而不是派生表,前提是您使用的 MySQL 版本支持它。

最终答案:

SELECT IC.id
     , IC.full_name
     , IC.location
     , IC.phone_number
     , ICD.icid
     , ICD.incdid
     , ICD.date_sub
     , ICD.date_exp
     , ICD.isPaid
     , ICD.sub_price 
FROM internetClient IC
LEFT JOIN (SELECT ICDi.*
           FROM internetclientdetails ICDi
           INNER JOIN (SELECT max(date_sub) MaxDateSub, ICID 
                       FROM internetclientdetails 
                       GROUP BY ICID) mICD
              ON ICDi.ICID = mICD.ICID
             AND ICDi.Date_Sub = mICD.MaxDateSub
           ) ICD
  on IC.id=ICD.icid 
ORDER BY ICD.incdid desc

分解/解释

下面为我们提供了 clientDetails 中每个 ICID 的 max(date_Sub) 子集。我们需要这样才能过滤掉所有不是每个 clientID 的最大日期的记录。

(SELECT max(date_sub) MaxDateSub, ICID 
 FROM internetclientdetails 
 GROUP BY ICID) mICD

使用该集合,我们加入了 Client_ID 和最大日期的详细信息,以消除每个客户的最新详细信息以外的所有信息。我们这样做是因为我们需要其他详细信息属性。这可以使用连接或存在来完成。我更喜欢 join 方法,因为它对我来说似乎更明确。

(SELECT ICDi.*
 FROM internetclientdetails ICDi
 INNER JOIN (SELECT max(date_sub) MaxDateSub, ICID 
             FROM internetclientdetails 
             GROUP BY ICID) mICD
    ON ICDi.ICID = mICD.ICID
   AND ICDi.Date_Sub = mICD.MaxDateSub
 ) ICD

最后,即使没有使用左连接的细节,完整查询也会将客户端连接到保留细节的客户端。

组件:

  • 您想要来自 InternetClient (FROM internetClient IC) 的所有记录
  • 您想要来自 InternetClientDetail (LEFT Join InternetClientDetail ICD) 的相关记录,同时保留来自 InternetClient 的记录。
  • 您只想要来自 InternetClientDetail 的最新记录(INNER JOIN InternetClientDetail mICD 作为获取 ICID 和 max(date) 的派生表)
  • 总记录数应该 = InternetClient 中的总记录数,这意味着所有关系在表连接上必须是 1:1o - 一对一可选。

【讨论】:

  • 更正了连接和一些别名拼写错误的几个问题。还添加了解释。
  • 这太棒了,像魅力一样工作,非常感谢:D,我整晚都在试图修复它。
  • 始终将问题分解为组件。每一步都变得更容易解决。一次解决所有问题可能很复杂。你怎么吃大象?一次一口。将每个方面分解成自己的组件,复杂的事情就变得非常简单。
  • 这太真实了
  • 对更新感到抱歉,我只是想让它变得漂亮,以防其他人觉得它有用;P
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-30
  • 1970-01-01
相关资源
最近更新 更多