2013-07-27 44 views
0

我从表中使用以下查询选择交易:如果子查询没有找到联结,如何忽略WHERE IN子句?

SELECT t.* 
FROM transactions AS t 
WHERE t.id IN 
(
    SELECT t2.id 
    FROM `virtual_account-account` AS vaa 
    LEFT JOIN transactions AS t2 
    ON t2.account = vaa.account 
    WHERE vaa.virtual_account = 3 
) 
AND t.id IN 
(
    SELECT tt.transaction 
    FROM `virtual_account-tag` AS vat 
    LEFT JOIN `transaction-tag` AS tt 
    ON tt.tag = vat.tag 
    WHERE vat.virtual_account = 3 
) 
ORDER BY t.date 

不过,我想修改该这样,如果,例如,结合表virtual_account-account不包含任何路口,其中vaa.virtual_account = 3,然后应该忽略相应的t.id IN (...)条件。到目前为止,我没有找到解决方案,所以任何帮助将不胜感激。

+0

怎么样,如果两个子选择返回任何结果?你想显示所有交易还是仅显示所有交易? –

+0

@FabianBigler其实,我不太在意这种情况,因为这是不可能发生的。然而,空的结果会比选择所有交易更好。 – Niko

回答

0

只是一个两个条件之间:

SELECT t.* 
FROM transactions AS t 
WHERE t.id IN 
(
    SELECT t2.id 
    FROM `virtual_account-account` AS vaa 
    LEFT JOIN transactions AS t2 
    ON t2.account = vaa.account 
    WHERE vaa.virtual_account = 3 
) 
OR t.id IN 
(
    SELECT tt.transaction 
    FROM `virtual_account-tag` AS vat 
    LEFT JOIN `transaction-tag` AS tt 
    ON tt.tag = vat.tag 
    WHERE vat.virtual_account = 3 
) 
ORDER BY t.date 

如果一个人没有返回,它仍然会返回其他交易。

+0

他说它应该被忽略 –

+0

感谢您的回应,但不幸的是,并非如此简单:如果在ID为3的两个联结表(虚拟账户 - 账户或虚拟账户 - 标签)都有条目,那么应该有AND条件。 – Niko

0

以下方法将子查询转换为联接并使用变量来计算子查询中的行数。该where条款然后使用这个变量为你想要的逻辑:

SELECT t.* 
FROM transactions t left outer join 
    (SELECT t2.id, @cnt := @cnt + 1 
     FROM `virtual_account-account` AS vaa 
      LEFT JOIN transactions AS t2 
      ON t2.account = vaa.account cross join 
      (select @cnt := 0) 
     WHERE vaa.virtual_account = 3 
     group by t2.id 
    ) c1 
    on c1.id = t.id 
WHERE (c1.id is not null or @cnt = 0) and 
     t.id IN (SELECT tt.transaction 
       FROM `virtual_account-tag` AS vat 
        LEFT JOIN `transaction-tag` AS tt 
        ON tt.tag = vat.tag 
       WHERE vat.virtual_account = 3 
    ) 
ORDER BY t.date; 

注意,子查询消除重复(使用group by)。否则,您可能会遇到导致多行的多个匹配问题。

0

有点笨拙和冗长,但是......

SELECT t.* 
FROM transactions AS t 
WHERE t.id IN 
(
    SELECT t2.id 
    FROM `virtual_account-account` AS vaa 
    LEFT JOIN transactions AS t2 
    ON t2.account = vaa.account 
    WHERE vaa.virtual_account = 3 
) 
AND t.id IN 
(
    SELECT tt.transaction 
    FROM `virtual_account-tag` AS vat 
    LEFT JOIN `transaction-tag` AS tt 
    ON tt.tag = vat.tag 
    WHERE vat.virtual_account = 3 
    AND EXISTS 
    (
     SELECT t2.id 
     FROM `virtual_account-account` AS vaa 
     LEFT JOIN transactions AS t2 
     ON t2.account = vaa.account 
     WHERE vaa.virtual_account = 3 
    ) 
) 
ORDER BY t.date 
0

尝试:

SELECT t.* 
FROM (select count(*) vaa 
     FROM `virtual_account-account` 
     WHERE virtual_account = 3) a 
CROSS JOIN (select count(*) vat 
      FROM `virtual_account-tag` 
      WHERE virtual_account = 3) g 
CROSS JOIN transactions AS t 
LEFT JOIN `virtual_account-account` vaa 
     ON t.id = vaa.id AND vaa.virtual_account = 3 
LEFT JOIN `virtual_account-tag` vat 
    JOIN `transaction-tag` tt ON tt.tag = vat.tag 
     ON t.id = tt.transaction AND vat.virtual_account = 3 
WHERE (a.vaa = 0 OR vaa.id IS NOT NULL) AND 
     (g.vat = 0 OR vat.tag IS NOT NULL) 
GROUP BY t.id 
ORDER BY t.date