0

私はこのように設計されたテーブルを持っています:

tbl_User
id
Name

tbl_User_Payment
id
user_id
amount
status

tbl_User
id      Name
001     John Doe
002     Juan Dela Cruz


tbl_User_Payment
id        user_id      amount        status
001         001          10         Successful
002         002          10         Fail
003         001          10         Fail
004         001          10         Fail
005         001          10         Fail
006         002          10         Successful
007         002          10         Fail
008         002          10         Fail

ここでの問題は、支払いが成功した後の支払い失敗の数をどのように数えることができるかということです。したがって、ここでの結果は次のようになります。

John Doe - 3 Failed Payment
Juan Dela Cruz - 2 Failed Payment

私がここで成し遂げようとしていることをご理解いただければ幸いです。

あなたの助けは大いに感謝され、報われるでしょう!

ありがとう!:)

4

4 に答える 4

1

簡潔さと明確さのために、コード内のいくつかのエイリアスを作成します。

SELECT
    Users.UserName,
    FailCount
FROM
    (
    SELECT
        UserId,
        COUNT(*) As FailCount
    FROM
        Payments,
        (
        SELECT
            UserId,
            MAX( PaymentId ) As LastSuccessId
        FROM
            Payments
        WHERE
            Status = Successful
        GROUP BY
            UserId
        ) AS LastSuccess
    WHERE
        PaymentId > LastSuccessId
    GROUP BY
        UserId
    ) As FailCount
    INNER JOIN Users ON Users.UserId = FailCount.UserId
ORDER BY
    UserName DESC

私は少し錆びています。このSQLはテストしていませんが、機能しない場合は、" FROM Payments, <subquery>"構文が原因であると思われます。私は自分の解決策を検証できる立場にないので、うまくいかない場合は誰かを雇って助けてもらう必要があるかもしれません。

あなたが疑問に思っているなら、ここに私の論理があります:

  1. 私のコードは、PaymentIdsが時系列で順番にインクリメントされることを前提として機能します。
  2. ユーザーごとに、最後に成功した支払いのIDを取得するクエリを実行します(最も内側SELECT)。
  3. Paymentsテーブルを再クエリしてCOUNT、最も内側のによって取得された「最後に成功した支払いID」値の後に来るユーザーごとの行の数を取得しますSELECT
  4. JOINユーザー名を取得するためのusersテーブルを使用したステップ3の結果。

また、将来のデータベース設計のためのいくつかのヒント:DB設計でハンガリアン記法を使用する必要はありません-「tbl_」プレフィックスが表示されるたびにうんざりします。また、主キーフィールドに単に「id」という名前を付けることはお勧めしません。これは、JOINを明確にする必要があるため、JOINがより困難になるためです。テーブルの名前を前に付けることを検討してください(たとえば、「payments.id」は「」になりPayments.PaymentIdます)。

于 2013-01-30T03:48:31.070 に答える
1

count関数とgroupbyステートメントを使用してみてください

例えば:

select Name, count(Status), Status from tbl_User as tu, tbl_User_Payment as tup where tup.user_id = tu.id group by status

それをチェックして、これが役立つかどうか私に知らせてください。

于 2013-01-30T03:51:25.967 に答える
1

このクエリを試してください

SELECT
      `user_id`,
      COUNT(id) AS "Total",
      SUM(CASE WHEN status= 'Fail' THEN 1 ELSE 0 END) AS "Failed",
      SUM(CASE WHEN status= 'Successful' THEN 1 ELSE 0 END) AS "Successful"
FROM `tbl_User_Payment`
GROUP BY `user_id`;
于 2013-01-30T03:55:05.273 に答える
-1

PHPバージョン。userこれは、テーブル内のすべての/行を実行しないように最適化できますtbl_Userが、ジョブは実行されます。

<?php

$mysqli = new mysqli('localhost', 'root', DB_PASSWORD, DB_NAME);

if ($mysqli->connect_error)
  die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);

$result = $mysqli->query("SELECT * FROM `tbl_User_Payment` WHERE `status` = 'Fail'"))
$array = [];
while ($col = $result->fetch_array(MYSQLI_ASSOC)) {
  if (array_key_exists($col['user_id'], $array))
    $array[$col['user_id']] = $array[$col['user_id']]+1;
  else
    $array[$col['user_id']] = 1;
}
$result->close();
$mysqli->close();


$mysqli = new mysqli('localhost', 'root', DB_PASSWORD, DB_NAME);

if ($mysqli->connect_error)
  die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);

$result = $mysqli->query("SELECT * FROM `tbl_User` WHERE 1"))
while ($col = $result->fetch_array(MYSQLI_ASSOC)) {
  if (array_key_exists($col['id'], $array))
    echo $col['Name'] . ' - ' . $array[$col['id']] . ' Failed attempts <br />';
}
$result->close();
$mysqli->close();

?>
于 2013-01-30T04:13:51.680 に答える