4

表: ローン

Loan_no     Amount        SSS_no              Loan_date

7           700.00        0104849222          2010-01-03 
8           200.00        0104849222          2010-02-28
9           300.00        0119611199          2010-11-18
10          150.00        3317131410          2012-11-28
11          600.00        0104849222          2011-01-03
14          175.00        3317131410          2012-12-05
15          260.00        3317131410          2013-02-08
16          230.00        0104849222          2013-03-06
17          265.00        0119611199          2011-04-30
18          455.00        3317131410          2013-03-10

望ましい結果:

各人が利用した最新のローンを取得したいと思います (SSS 番号で識別されます)。結果は次のようになります。

Loan_no           Amount                SSS_no                Loan_date

16                230.00              0104849222              2013-03-06
17                265.00              0119611199              2011-04-30
18                455.00              3317131410              2013-03-10

クエリ # 1 を使用:

SELECT * FROM loan GROUP BY SSS_no ORDER BY Loan_date DESC

MYSQL の結果

Loan_no             Amount              SSS_no                  Loan_date

10                  150.00            3317131410                2012-11-28
9                   300.00            0119611199                2010-11-18
7                   700.00            0104849222                2010-01-03

クエリ # 2 を使用:

SELECT Loan_no, Amount, SSS_no, max(Loan_date) FROM loan GROUP BY SSS_no

MYSQL の結果

Loan_no            Amount                SSS_no                Loan_date

7                  700.00                0104849222            2013-03-06
9                  300.00                0119611199            2011-04-30
10                 150.00                3317131410            2013-03-10

誰でも私の問題を解決できますか? ありがとう。

4

3 に答える 3

1

予期しない結果が得られる理由は、リストGROUP BY内の 1 つの列のみでを使用SELECTしており、すべての列で集計関数を使用していないためです。

MySQL は、リスト内のすべての項目を集計GROUP BYしないか集計しない場合に予期しない結果を引き起こす可能性がある関数の拡張機能を使用します。( GROUP BY に対する MySQL 拡張機能を参照してください)GROUP BYSELECT

MySQL ドキュメントから:

MySQL は GROUP BY の使用を拡張して、選択リストが GROUP BY 句で指定されていない非集計列を参照できるようにします。... この機能を使用して、不要な列の並べ替えやグループ化を回避することで、パフォーマンスを向上させることができます。ただし、これは主に、GROUP BY で指定されていない各非集計列のすべての値が各グループで同じ場合に役立ちます。サーバーは各グループから任意の値を自由に選択できるため、それらが同じでない限り、選択された値は不確定です。さらに、ORDER BY 句を追加しても、各グループからの値の選択に影響を与えることはできません。結果セットのソートは値が選択された後に行われ、ORDER BY はサーバーが選択する値には影響しません。

確実に正しい結果を返す唯一の方法は、クエリをGROUP BY適切に集計するように変更することです。

したがって、次のようなものを使用できます。

select l1.loan_no,
  l1.amount,
  l1.SSS_no,
  l1.loan_date
from loan l1
inner join
(
  select SSS_no, max(loan_date) Loan_date
  from loan
  group by SSS_no
) l2
  on l1.SSS_no = l2.SSS_no
  and l1.loan_date = l2.loan_date

デモで SQL Fiddle を参照してください

max(loan_date)これは、 for eachを取得するサブクエリを実装しますSSS_no。このサブクエリは、SSS_noと max の両方でテーブルに結合されます。loan_dateこれにより、各 に対して正しい結果が得られることが保証されますSSS_no

于 2013-03-25T11:21:17.913 に答える
1

MySQLのリファレンスでは、これを解決する方法がいくつか提案されています。最も単純なのはサブクエリです。

SELECT *
FROM   loan l1
WHERE  loan_date=(SELECT MAX(l2.loan_date)
              FROM loan l2
              WHERE l1.sss_no = l2.sss_no);

このタイプのサブクエリはパフォーマンスが悪い可能性がJOINあるため、 (本質的にマフムード ガマルの回答)を使用することも提案されています。

SELECT l1.loan_no, l1.amount, l1.sss_no, l1.loan_date
FROM loan l1
JOIN (
  SELECT loan_no, MAX(loan_date) AS loan_date
  FROM loan
  GROUP BY sss_no) AS l2
  ON l1.loan_date = l2.loan_date AND l1.sss_no = l2.sss_no;

3 番目のオプションは次のとおりです。

SELECT l1.loan_no, l1.amount, l1.sss_no, l1.loan_date
FROM loan l1
LEFT JOIN loan l2 ON l1.sss_no = l2.sss_no AND l1.loan_date < l2.loan_date
WHERE l2.sss_no IS NULL;

がその最大値にあるLEFT JOINとき、後で があることに基づいて動作するため、l2 行の値は NULL になります。l1.loan_datel2.loan_date

これらはすべて同じ出力になるはずですが、パフォーマンスが異なる可能性があります。

于 2013-03-25T11:14:18.287 に答える
1

代わりにこれを試してください:

SELECT l1.*
FROM loan AS l1
INNER JOIN
(
   SELECT SSS_no, MAX(Loan_date) LatestDate
   FROM loan
   GROUP BY SSS_no
) AS l2  ON l1.SSS_no    = l2.SSS_no 
        AND l1.loan_date = l2.LatestDate;

SQL フィドルのデモ

これにより、次のことが得られます。

| LOAN_NO | AMOUNT |     SSS_NO |  LOAN_DATE |
----------------------------------------------
|      16 |    230 |  104849222 | 2013-03-06 |
|      17 |    265 |  119611199 | 2011-04-30 |
|      18 |    455 | 3317131410 | 2013-03-10 |
于 2013-03-25T10:58:45.873 に答える