表多个Sql查询联盟

时间:2015-07-11 20:57:37

标签: sql

我有以下表格,其中有不同字段的重复记录:

CREATE TABLE Student1
    (`id` int,`status` int,`amount` int , `Name` varchar(10), `date` varchar(55))
;
    INSERT INTO Student1
    (`id`,`status`,`amount`, `Name`, `date`)
VALUES
    (1,0,4500, 'ram', '04/02/2012'),
    (2,0,2000, 'shyam', '05/09/2013'),
    (4,0,1500, 'ghanshyam', '08/11/2014'),
    (3,0,4500, 'gopal', '04/02/2012'),
    (2,0,8000, 'radheshyam', '15/11/2013'),
    (4,1,1500, 'ghanshyam', '18/10/2015'),
    (1,1,4500, 'ram', '14/02/2012'),
    (2,0,6500, 'radhe', '11/11/2014'),
    (3,1,4500, 'gopal', '14/02/2015'),
    (5,1,4500, 'gopala', '04/02/2015'),
    (5,1,4500, 'gopala', '04/02/2015'),
    (6,0,14500, 'gopal', '14/02/2015')
; 

我有3个条件来过滤表格:

  1. 没有完整的重复记录
  2. 如果记录具有相同的id但不同的Namedate字段,则将所有这些记录添加到最终结果中
  3. 如果status=1为任何记录,则选择相应id
  4. 的记录
  5. 添加id与上述3个条件id不同的所有记录
  6. 我写了这个查询:

    SELECT * FROM Student1 
    GROUP BY id,status,amount,Name,date
    HAVING COUNT(*) > 1
    
    UNION 
    
    SELECT * FROM Student1  Student1
    WHERE id IN
    (
    SELECT id FROM Student1
    GROUP BY id
    HAVING COUNT(DISTINCT name) > 1
    AND COUNT(DISTINCT date) > 1
    )
    
    UNION 
    
    SELECT * FROM Student1  Student1
    WHERE status=1 AND id IN
    (
    SELECT id FROM Student1
    GROUP BY id
    HAVING COUNT(id) >= 2
    );
    

    结果:

    id  status  amount  Name    date
    4   1   1500    ghanshyam   18/10/2015
    1   1   4500    ram 14/02/2012
    3   1   4500    gopal   14/02/2015
    5   1   4500    gopala  04/02/2015
    2   0   2000    shyam   05/09/2013
    2   0   8000    radheshyam  15/11/2013
    2   0   6500    radhe   11/11/2014
    

    正如您所见,第一选择避免重复,第二选择记录使相同的id具有不同的Namedate,第三选择以获得id=1的记录。我使用UNION来避免重复结果。

    现在我需要添加第4个查询来获取在上述所有情况下都不存在的记录id=6

    预期结果:

    id  status  amount  Name    date
    4   1   1500    ghanshyam   18/10/2015
    1   1   4500    ram 14/02/2012
    3   1   4500    gopal   14/02/2015
    5   1   4500    gopala  04/02/2015
    2   0   2000    shyam   05/09/2013
    2   0   8000    radheshyam  15/11/2013
    2   0   6500    radhe   11/11/2014
    6   0   14500   gopal   14/02/2015
    

    我需要解决第4个问题。请帮忙。

1 个答案:

答案 0 :(得分:0)

如果您要过滤的唯一条件是id = 6,则只需添加:

SELECT * FROM Student1 WHERE id=6;

您的请求直接转换为SQL。完整版将是:

SELECT * FROM Student1 
  GROUP BY id,status,amount,Name,date
  HAVING COUNT(*) > 1

UNION 

SELECT * FROM Student1  Student1
  WHERE id IN
  (
  SELECT id FROM Student1
  GROUP BY id
  HAVING COUNT(DISTINCT name) > 1
  AND COUNT(DISTINCT date) > 1
  )

UNION 

SELECT * FROM Student1  Student1
  WHERE status=1 AND id IN
  (
  SELECT id FROM Student1
  GROUP BY id
  HAVING COUNT(id) >= 2
  )

UNION 

SELECT * FROM Student1 WHERE id=6;

结果按要求提供,但顺序不同。 DEMO

但是,如果您希望获得未使用您的编码过滤的所有id,但您不知道其值,我会使用VIEW

CREATE VIEW Student2 AS 
  SELECT * FROM Student1 
  GROUP BY id,status,amount,Name,date
  HAVING COUNT(*) > 1

UNION 

SELECT * FROM Student1  Student1
  WHERE id IN
  (
  SELECT id FROM Student1
  GROUP BY id
  HAVING COUNT(DISTINCT name) > 1
  AND COUNT(DISTINCT date) > 1
  )

UNION 

SELECT * FROM Student1  Student1
  WHERE status=1 AND id IN
  (
  SELECT id FROM Student1
  GROUP BY id
  HAVING COUNT(id) >= 2
);

And then query with it:

SELECT * FROM Student2

UNION 

SELECT * FROM Student1 WHERE id NOT IN (SELECT id FROM Student2);

结果是一样的。 DEMO