3

1つのクエリで苦労しています。LEFT JOIN特定のIDが一致し、日付が異なる2つのテーブルが必要です。

SELECT
    *
FROM
    u_data ud
JOIN
    u_contracts uc
ON
    uc.user_id = ud.id
LEFT JOIN
    u_transactions ut
ON
    ut.contract_id = uc.id
    /* AND DATE( ut.add_timestamp ) > DATE( ud.suspicious ) */
WHERE
    ud.suspicious > 0
    AND ud.suspicious != ''
    AND ud.suspicious IS NOT NULL
    AND uc._status = 6
GROUP BY
    ud.id;

これにより、正しい行数が得られますが、トランザクションの日付が最初のテーブルの疑わしい日付よりも大きいかどうかも確認する必要があります。その条件を追加するとすぐに(開始時にも試行されます)、トランザクションの日付がないすべてのフィールドが削除されます。

つまり、LEFT JOINこれらのテーブルを使用すると、次のような結果が得られます。

+-----+----------+---------------+---------------+--------+
| row | original | ud.suspicious | add_timestamp | amount |
+-----+----------+---------------+---------------+--------+
|   1 |      100 | 10.01.2000    | 01.01.2000    |     50 |
|   2 |      100 | 10.01.2000    | NULL          | NULL   |
|   3 |      100 | 10.01.2000    | 12.01.2000    |     10 |
|   4 |      100 | 11.01.2000    | 12.01.2000    |     20 |
|   5 |      100 | 12.01.2000    | 12.01.2000    |     30 |
+-----+----------+---------------+---------------+--------+

さて、基本的には金額と日付を削除する必要があります。01.01.2000これは、疑わしい日付よりも古く、追加の金額は必要ないためですが、元の金額が必要です。これは私が取得する必要があるものです

+-----+----------+---------------+---------------+--------+
| row | original | ud.suspicious | add_timestamp | amount |
+-----+----------+---------------+---------------+--------+
|   1 |      100 | 10.01.2000    | NULL          | NULL   |
|   2 |      100 | 10.01.2000    | NULL          | NULL   |
|   3 |      100 | 10.01.2000    | 12.01.2000    |     10 |
|   4 |      100 | 11.01.2000    | 12.01.2000    |     20 |
|   5 |      100 | 12.01.2000    | 12.01.2000    |     30 |
+-----+----------+---------------+---------------+--------+

しかし、その条件を設定すると、次のDATE( ut.add_timestamp ) > DATE( ud.suspicious )ようになります。

+-----+----------+---------------+---------------+--------+
| row | original | ud.suspicious | add_timestamp | amount |
+-----+----------+---------------+---------------+--------+
|   1 |      100 | 10.01.2000    | 12.01.2000    |     10 |
|   2 |      100 | 11.01.2000    | 12.01.2000    |     20 |
|   3 |      100 | 12.01.2000    | 12.01.2000    |     30 |
+-----+----------+---------------+---------------+--------+

でエントリを削除するのはなぜLEFT JOINですか?必要な正しいデータを取得するためにこれを修正するにはどうすればよいですか?


編集:完全な元の作業クエリ:

SELECT
    ud.Pcode AS pcode
    , CONCAT( ud.Name, ' ', ud.Surname ) AS name
    , CONCAT(
        ud.Da_CityName,
        IF ( ud.Da_Street != '', CONCAT( ', ', ud.Da_Street ), '' ),
        IF ( ud.Da_Housen != '', CONCAT( ', ', ud.Da_Housen ), '' ),
        IF ( ud.Da_Flatn != '', CONCAT( ', ', ud.Da_Flatn ), '' ),
        IF ( ud.Da_PostIndex != '', CONCAT( ', ', ud.Da_PostIndex ), '' )
    ) AS address
    , uc.id AS contract_id
    , uc.terminate_date AS terminate_date
    , FORMAT( IF ( (
        SELECT
            SUM( external_account )
        FROM
            u_transactions
        WHERE
            contract_id = uc.id 
            AND nulled = 0
            AND type in ( 'penalty', 'initial', 'comission', 'penalty2', 'penalty2_vat' )
            AND DATE( add_timestamp ) > DATE( ud.suspicious )
    ) IS NULL, uc.inkasso_debt, uc.inkasso_debt - (
        SELECT
            SUM( external_account )
        FROM
            u_transactions
        WHERE
            contract_id = uc.id 
            AND nulled = 0
            AND type in ( 'penalty', 'initial', 'comission', 'penalty2', 'penalty2_vat' )
            AND DATE( add_timestamp ) > DATE( ud.suspicious )
    ) ), 2 ) AS summ
FROM
    u_data ud
JOIN
    u_contracts uc
ON
    uc.user_id = ud.id
WHERE
    ud.suspicious > 0
    AND ud.suspicious != ''
    AND ud.suspicious IS NOT NULL
    AND uc._status = 6
    AND DATE( uc.terminate_date ) < ( NOW() - INTERVAL 45 DAY )

面倒なので、2つの副選択を取り除き、それらを結合してSUM( external_account )金額を取得しようとしています。多分これは私の問題を理解するのに役立つでしょう。

4

5 に答える 5

1

試す:

SELECT
    row, original, ud.suspicious, isnull(u_transaction, '') as u_transaction, isnull(amount, '')
FROM
    u_data ud
JOIN
    u_contracts uc
ON
    uc.user_id = ud.id
LEFT JOIN
    u_transactions ut
ON
    ut.contract_id = uc.id
    AND DATE( ut.add_timestamp ) > DATE( ud.suspicious )
WHERE
    ud.suspicious > 0
    AND ud.suspicious != ''
    AND ud.suspicious IS NOT NULL
    AND uc._status = 6
GROUP BY
    ud.id;

それがうまくいくかどうかはわかりませんが、試す時間はありませんが、同じような問題があり、そのように解決したことを思い出します。

于 2013-02-15T09:19:26.340 に答える
1

ANDをON条件で使用しているため、u_transactionとamountにNULLが与えられていると思います。これをwhere句に入れて、何が起こるかを確認してください。

これを試して

SELECT
    *
FROM
    u_data ud
JOIN
    u_contracts uc
ON
    uc.user_id = ud.id
LEFT JOIN
    u_transactions ut
ON
    ut.contract_id = uc.id

WHERE
    ud.suspicious > 0
    AND ud.suspicious != ''
    AND ud.suspicious IS NOT NULL
    AND uc._status = 6
    AND DATE( ut.add_timestamp ) > DATE( ud.suspicious )
GROUP BY
    ud.id;
于 2013-02-15T09:24:52.197 に答える
1

試す

...
RIGHT JOIN u_transactions ut
ON ut.contract_id = uc.id
AND ( DATE( ut.add_timestamp ) > DATE( ud.suspicious )
      OR ut.add_timestamp IS NULL )
...

クエリで

于 2013-02-15T09:47:32.040 に答える
0

必要なのが出力にNULL文字列である場合は、selectステートメントにIFステートメントを追加します。

SELECT
  IF(
     DATE( ut.add_timestamp ) < DATE( ud.suspicious ),
     'NULL',
     ud.add_timestamp
    ) AS add_timestamp
FROM
  -----Rest of the query-----

更新された投稿に基づいて、以下は私のバージョンのクエリです。このクエリで問題が解決しない場合は、sqlfiddle.comでテーブル構造を作成できると非常に役立ちます。

SELECT  

  FORMAT(
     IF(                
            SUM(external_account) IS NULL,                                  
            uc.inkasso_debt,
            uc.inkasso_debt -  SUM( external_account)
    ), 2) AS summ

FROM
    u_data ud
    JOIN u_contracts uc ON uc.user_id = ud.id
    LEFT JOIN u_transactions ON (   
                               u_transactions.contract_id = uc.id                                                                        
                               AND nulled = 0                                                                          
                               AND (type in ( 'penalty', 'initial', 'comission', 'penalty2', 'penalty2_vat' ))
                               AND DATE(u_transactions.add_timestamp ) > DATE( ud.suspicious )                                                                  
                            )                                                                     


WHERE
  ud.suspicious > 0   
  AND uc._status = 6
  AND DATE( uc.terminate_date ) < ( NOW() - INTERVAL 45 DAY )

GROUP BY
  ud.id
于 2013-02-15T09:46:34.917 に答える
0

OUTER結合を使用したOR条件で、正しい結果が返されることは期待できません。比較列にNULLがあるため、技術的には「値なし」を示すため、比較に対して「true」が返されることはありません。あなたの場合、結合条件が評価される前に、NULLを常に真である値に置き換える必要があるかもしれません。以下のようなもの。

LEFT JOIN u_transactions ut ON ut.contract_id = uc.id AND(isnull(DATE(ut.add_timestamp)、DATEADD(dd、1、DATE(ud.suspicious)))> DATE(ud.suspicious))

于 2015-04-29T22:13:33.353 に答える