简体   繁体   English

在具有6个联接表的选择查询期间检索到错误的ID

[英]Wrong ID is retrieve during a select query with 6 joined tables

This are my tables: 这是我的表:

cb_paymentscheduledetail cb_paymentscheduledetail

id | name                  | date_entered          | deleted | due_date   | amount | status
1  | #1 Payment For Inv# 1 | 2016-07-15 06:11:55   | 0       | 2016-07-08 | 147.25 | Unpaid
2  | #2 Payment For Inv# 1 | 2016-07-15 06:11:55   | 0       | 2016-07-15 | 147.25 | Unpaid
3  | #1 Payment For Inv# 3 | 2016-07-14 13:00:21   | 0       | 2016-07-18 | 4.58   | Unpaid
4  | #2 Payment For Inv# 3 | 2016-07-14 13:00:21   | 0       | 2016-07-21 | 4.58   | Unpaid
5  | #1 Payment For Inv# 2 | 2016-07-14 12:56:35   | 0       | 2016-07-22 | 50.00  | Unpaid
6  | #3 Payment For Inv# 1 | 2016-07-15 06:11:55   | 0       | 2016-07-22 | 147.25 | Unpaid

cb_paymentscheduleheader cb_paymentscheduleheader

id  |  installment_type
1   |  auto
2   |  auto
3   |  manual

cb_paymentscheduleheader_cb_paymentscheduledetail_c cb_paymentscheduleheader_cb_paymentscheduledetail_c

id | cb_payment37a2eheader_ida | cb_paymente42dedetail_idb
1  | 1                         | 5
2  | 2                         | 6
3  | 2                         | 1
4  | 2                         | 2
5  | 3                         | 3
6  | 3                         | 4

aos_invoices aos_invoices

id | number | billing_account_id
1  | 1      | 1
2  | 2      | 2
3  | 3      | 3

accounts 帐目

id | phone_office | name
1  | 123          | a
2  | 123          | b
3  | 123          | c

email_addr_bean_rel email_addr_bean_rel

email_address_id | bean_id
1                | 1
2                | 2
3                | 3

email_addresses 电子邮件地址

id | email_address
1  | test@test.com
2  | test@test3.com
3  | test@test4.com

My Query: 我的查询:

SELECT cb_paymentscheduledetail.id , cb_paymentscheduledetail.amount , cb_paymentscheduledetail.assigned_user_id 
    ,MIN(cb_paymentscheduledetail.due_date) as min_date, cb_paymentscheduledetail.name, 
    cb_paymentscheduledetail.amount, aos_invoices.number, aos_invoices.billing_account_id,
    accounts.id as account_id, accounts.phone_office as account_phone, accounts.name as account_name, 
    email_addr_bean_rel.email_address_id, email_addr_bean_rel.bean_id, email_addresses.email_address as account_email, 
    cb_paymentscheduleheader_cb_paymentscheduledetail_c.id as headerdetail_id, 
    cb_paymentscheduleheader_cb_paymentscheduledetail_c.cb_paymente42dedetail_idb, 
    cb_paymentscheduleheader_cb_paymentscheduledetail_c.cb_payment37a2eheader_ida, cb_paymentscheduleheader.id as header_id, 
    cb_paymentscheduleheader.installment_type  
    FROM cb_paymentscheduledetail  
    LEFT JOIN aos_invoices ON aos_invoices.number = SUBSTRING_INDEX(cb_paymentscheduledetail.name, ' ', -1) 
    INNER JOIN accounts ON aos_invoices.billing_account_id = accounts.id 
    INNER JOIN email_addr_bean_rel ON accounts.id = email_addr_bean_rel.bean_id 
    INNER JOIN email_addresses ON email_addresses.id = email_addr_bean_rel.email_address_id  
    INNER JOIN cb_paymentscheduleheader_cb_paymentscheduledetail_c ON cb_paymentscheduledetail.id = cb_paymentscheduleheader_cb_paymentscheduledetail_c.cb_paymente42dedetail_idb  
    INNER JOIN cb_paymentscheduleheader ON cb_paymentscheduleheader_cb_paymentscheduledetail_c.cb_payment37a2eheader_ida = cb_paymentscheduleheader.id    
    WHERE cb_paymentscheduledetail.deleted = 0 AND cb_paymentscheduledetail.status = 'Unpaid' AND (cb_paymentscheduledetail.due_date BETWEEN '2016-07-15' AND '2016-07-22') 
    GROUP BY cb_paymentscheduledetail.date_entered 
    ORDER BY cb_paymentscheduledetail.due_date ASC;

My problem here is that the ID fetch by this query is not correct for amount 147.25 altough the min_date it fetch is correct: 我的问题是,此查询提取的ID在正确的min_date内对于数量147.25是不正确的:

the min_date queried is as follow: 查询的min_date如下:

4.58 = 2016-07-18
50.00 = 2016-07-22
147.25 = 2016-07-15

There ID should be this respectively: ID应分别为:

4.58 = 3
50.00 = 5
147.25 = 2

But the actual ID is: 但是实际的ID是:

4.58 = 3
50.00 = 5
147.25 = 6

As you can see for amount "147.25" it is getting due_date 2016-07-22 when in the MIN function it got the correct one which is 2016-07-15, it is also getting the correct ID which should be 2 and not 6, Will anyone be able to help me with this as I cannot really see anymore what the problem is? 如您所见,金额“ 147.25”的到期日为2016-07-22,而在MIN函数中,该帐户的正确号码为2016-07-15,它的ID也为2,而不是6 ,由于我再也看不到问题所在了,因此有人可以帮助我吗? since shouldn't it retrieve the appropriate ID based on my min_date when it got that correct from the start? 因为当它一开始就正确时,它是否不应该根据我的min_date检索适当的ID?

The only time 2016-07-15 is selected is when I change my BETWEEN to: 当我将BETWEEN更改为时,唯一一次选择2016-07-15:

cb_paymentscheduledetail.due_date = '2016-07-15'

But I don't what this since I need to get the in between date 但是我什么都不是,因为我需要在两次约会之间

shouldn't it retrieve the appropriate ID based on my min_date when it got that correct from the start? 从一开始就确定正确的ID是否应该根据我的min_date检索适当的ID?

The short answer is No . 简短的答案是“ 否”

MySQL returns some values that seem random to you for all the expressions present in the SELECT clause that do not match one of the following: 对于不符合以下条件之一的SELECT子句中存在的所有表达式,MySQL返回的一些值对您来说似乎是随机的:

  • the expression is also present in the GROUP BY clause; 该表达式也存在于GROUP BY子句中;
  • the expression uses GROUP BY aggregate functions ; 该表达式使用GROUP BY aggregate functions ;
  • the expression is functionally dependent on the columns that appear in the GROUP BY clause. 该表达式在功能上取决于GROUP BY子句中出现的列。

It is a documented behaviour and it is how it should be because of the way the GROUP BY works. 这是一个已记录的行为 ,由于GROUP BY工作方式,因此应该是这样。

GROUP BY does not select rows from the database. GROUP BY 不会从数据库中选择行。 It generates records using the values from the database. 它使用数据库中的值生成记录。 Each expression that appears in the SELECT clause of a query that also contains a GROUP BY clause is computed independent of the other expressions. 查询的SELECT子句中还包含GROUP BY子句的每个表达式都是独立于其他表达式进行计算的。

Think a little about it. 想一想。 Assuming it should work as you want, what values should the query return if you replace MIN() with another GROUP BY aggregate function ? 假设它应该按您希望的那样工作,如果用另一个GROUP BY aggregate function替换MIN() ,查询应该返回什么值? With AVG() , for example. AVG()为例。 Most probably, there isn't any row in the cb_paymentscheduledetail table having in column due_date the value returned by AVG(due_date) . 最可能的是,没有在任何行cb_paymentscheduledetail具有列的表due_date返回的值AVG(due_date) Or COUNT() ? 还是COUNT() They doesn't even have the same type. 他们甚至没有相同的类型。

Take a look at this answer provided on a similar question to learn the correct way to write a query that returns the row having the minimum/maximum value from its group in a certain column. 看一下在类似问题上提供的答案 ,以学习编写查询的正确方法,该查询从某一列的组中返回具有最小值/最大值的行。 It can be expanded to accommodate six tables by INNER JOIN -ing them with the table from which the row is selected (table o in that answer). 可以通过INNER JOIN扩展为容纳六张表-将它们与从中选择行的表(该答案中的表o )配合使用。

If you cannot handle it this way, you can split your query into two smaller queries (you can even merge them later using subqueries): one query on paymentscheduledetail that selects MIN(due_date) and groups by date_entered and another query that uses the value returned by the first query to select the desired row(s). 如果您无法通过这种方式进行处理,则可以将查询分为两个较小的查询(甚至可以稍后使用子查询将其合并):一个关于paymentscheduledetail查询,选择MIN(due_date)并按date_entered ,另一个查询使用返回的值通过第一个查询选择所需的行。 Take into account that there can be more than one row that have in due_date the minimum value. 考虑到在due_date可以有多于一行的最小值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM