如何从多个表中选择具有可变条件的数据| MySQL的

时间:2018-05-24 10:53:03

标签: mysql sql database select join

我在数据库中有两个表来存储客户端基本信息(名称,位置,电话号码)和另一个存储客户端相关事务的表(date_sub,profile_sub,isPaid,date_exp,client_id),我有一个html表来查看客户端基本信息和交易如果可用,我的问题是我无法同时从表 internetClient internetclientDetails 中选择客户信息,因为查询仅在客户端在详细信息表中具有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

提前致谢

2 个答案:

答案 0 :(得分:2)

尝试使用左连接。它将显示来自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

答案 1 :(得分:1)

<强>概要

我们生成一个仅包含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

BREAKDOWN / EXPLANATION

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

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

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

(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和最大值(日期))
  • 总记录数应该= InternetClient中的总记录数,这意味着表连接上的所有关系必须是1:1o - 一对一可选。