制定查询以检测不一致的数据

时间:2011-12-12 20:11:49

标签: mysql sql

我有以下表结构:

CREATE TABLE a (
 a_id int(10) unsigned NOT NULL AUTO_INCREMENT,
);

CREATE TABLE b {
 b_id int(10) unsigned NOT NULL AUTO_INCREMENT,
};

CREATE TABLE cross (
 a_id int(10) unsigned NOT NULL,
 b_id int(10) unsigned NOT NULL,
 PRIMARY KEY (a_id),
 KEY (b_id),
 CONSTRAINT FOREIGN KEY (a_id) REFERENCES a (a_id),
 CONSTRAINT FOREIGN KEY (b_id) REFERENCES b (b_id)
);

CREATE TABLE prices (
 a_id int(10) unsigned NOT NULL,
 price int(10) NOT NULL,
 PRIMARY KEY (a_id),
 CONSTRAINT FOREIGN KEY (a_id) REFERENCES a (a_id)
);

我想检索价格不一致的每个b_id值。如果满足以下条件,则b.id值“B”的价格不一致:

  1. 存在两个a_id值(例如,'A1'和'A2'),使得表cross包含('A1','B')和('A2','B')。 (对于任何b_id值,cross中可能有零行或多行。)
  2. “A1”和“A2”对应的prices行具有不同的price值,或者“A1”和“A2”中的一个对应{{1}中的一个条目1}}。
  3. 由于托管服务提供商的限制,我无法使用此数据库的存储过程。我还没有找到一种合理的方法来使用SQL查询。到目前为止,我已经使用检索所有相关数据并扫描Perl中的不一致性。这是很多数据检索。有没有更好的办法? (我正在使用InnoDB,如果它有所作为。)

1 个答案:

答案 0 :(得分:3)

/* Condition 1 and Condition 2a */ 
SELECT 
    c.b_id
FROM
    `cross` AS c
    JOIN prices AS p ON (p.a_id = c.a_id)
GROUP BY
    c.b_id
HAVING
    COUNT(c.a_id) > 1 AND
    MAX(p.price) != MIN(p.price)

UNION

/* Condition 1 and Condition 2b */
SELECT 
    c.b_id
FROM
    `cross` AS c
    LEFT JOIN prices AS p ON (p.a_id = c.a_id)
GROUP BY
    c.b_id
HAVING
    COUNT(c.a_id) > 1 AND
    SUM(IF(p.price IS NULL, 0 ,1)) = 1;