3

我正在为一个查询而苦苦挣扎。我需要LEFT JOIN两个表,其中特定 id 匹配且日期不同:

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 )

由于它太乱了,我试图摆脱两个子选择并加入它们以获得SUM( external_account )数量。也许这将有助于理解我的问题。

4

5 回答 5

1

我认为它在 u_transaction 和 amount 中给出了 NULL,因为您使用 AND 和 ON 条件,尝试将它放在 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

尝试:

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

尝试

...
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 替换为始终为 true 的值。像下面的东西..

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 回答