SQL - 匹配两行的条件

时间:2015-01-06 06:05:12

标签: mysql sql select mysqldump

我正在尝试从SQL开发人员中提取匹配两行条件的数据。这两行都有一个唯一值(ID),表名是abc.tcd

ID  =  Type =   GL code = amount
1   =   Debit =  0701  =  10000
1  =    credit = 0601 =   10000
1  =    Credit=  0501  =  1000
1   =   Debit=   0401   = 1000
2   =   Debit =  0701  =  9000
2   =   credit = 0801  =  9000
3   =   Debit  = 0701  =  6000
3   =   credit = 0601  =  6000

条件1:

GL code = '0701'   having Type = 'Debit' 

条件2:

GL code = '0601'   having Type = 'Credit' 

预期产出:

ID    Type    GL code  amount

1  =    Debit  = 0701 =   10000
1  =    credit = 0601 =   10000
1  =    Credit = 0501 =   1000
1  =    Debit  = 0401 =   1000
3  =    Debit  = 0701 =   6000
3  =    credit = 0601 =   6000

输出应显示基于ID

的所有行

2 个答案:

答案 0 :(得分:2)

如果我正确理解了这个问题,您想要提取某些ID的所有行,其中两个不同的行满足两个不同的条件。您可以使用几个in运算符:

SELECT *
FROM   mytable
WHERE  id IN (SELECT id
              FROM   my_table
              WHERE  GLCode = '0701' AND Type = 'Debit')
        AND id IN (SELECT id
                   FROM   my_table
                   WHERE  GLCode = '0601' AND Type = 'Credit')

当然,这可以很容易地转换为使用exists运算符:

SELECT *
FROM   mytable a
WHERE  EXISTS (SELECT *
               FROM   my_table b
               WHERE  a.id = b.id AND b.GLCode = '0701' AND b.Type = 'Debit')
        AND EXISTS (SELECT *
                    FROM   my_table c
                    WHERE  a.id = c.id AND c.GLCode = '0601' AND c.Type = 'Credit')

更优雅的方法可能是在orcount单个查询中包含所有条件,其中有多少条件符合要求:

SELECT *
FROM   mytable
WHERE  id IN (SELECT   id
              FROM     my_table
              WHERE    (GLCode = '0701' AND Type = 'Debit') OR
                       (GLCode = '0601' AND Type = 'Credit')
              GROUP BY id
              HAVING   COUNT(*) = 2)

答案 1 :(得分:1)

另一种选择:

SELECT * FROM MyTable
INNER JOIN
(
  SELECT ID
  FROM MyTable
  WHERE (GLCode = '0701' AND Type = 'Debit') OR (GLCode = '0601' AND Type = 'Credit')
  GROUP BY ID
  HAVING COUNT(DISTINCT GLCode) = 2 AND COUNT(DISTINCT Type) = 2
) X
ON MyTable.ID = x.ID;

SqlFiddle here

基本上"找到具有符合标准的两个不同行的ID"。然后我们返回具有此ID的所有行

修改

您的真实查询如下:

SELECT *
FROM tbaadm.ctd 
INNER JOIN
(SELECT Tran_id 
    FROM tbaadm.ctd 
    WHERE ((GL_SUB_HEAD_CODE = '06106' AND PART_TRAN_TYPE = 'C') 
          OR (GL_SUB_HEAD_CODE = '29101' AND PART_TRAN_TYPE = 'D'))
       AND (tran_date >= '01-12-2014' AND tran_date < '30-12-2014')
    GROUP BY Tran_id
    HAVING COUNT(DISTINCT GL_SUB_HEAD_CODE) = 2 AND COUNT(DISTINCT PART_TRAN_TYPE) = 2
) X
ON tbaadm.ctd = x.Tran_id;

由于运算符优先级,ANDs周围的括号显然是多余的,但可能有助于提高可读性?

此外,请注意日期范围检查是否包含开始日期但排除结束日期,即x >= start and x < end