Here is before trigger you can use to guarantee that id1 and id2 are inserted in min/max order
DELIMITER $$
CREATE TRIGGER mytable_bi BEFORE INSERT ON mytable
FOR EACH ROW
BEGIN
DECLARE sum INT;
SET sum = NEW.id1 + NEW.id2;
SET NEW.id1 = (NEW.id1 + NEW.id2 - ABS(NEW.id1 - NEW.id2)) / 2;
SET NEW.id2 = sum - NEW.id1;
END $$
DELIMITER ;
Here is some Sample Data:
DROP DATABASE IF EXISTS ryanzec;
CREATE DATABASE ryanzec;
USE ryanzec
CREATE TABLE mytable
(
id1 INT NOT NULL,
id2 INT NOT NULL,
mapTypeId INT NOT NULL,
primary key (id1,id2)
);
DELIMITER $$
CREATE TRIGGER mytable_bi BEFORE INSERT ON mytable
FOR EACH ROW
BEGIN
DECLARE sum INT;
SET sum = NEW.id1 + NEW.id2;
SET NEW.id1 = (NEW.id1 + NEW.id2 - ABS(NEW.id1 - NEW.id2)) / 2;
SET NEW.id2 = sum - NEW.id1;
END $$
DELIMITER ;
INSERT INTO mytable VALUES (1,2,3);
INSERT INTO mytable VALUES (2,1,3);
INSERT INTO mytable VALUES (5,4,6);
INSERT INTO mytable VALUES (4,5,6);
SELECT * FROM mytable;
Here it is the Sample Data Loaded
mysql> DROP DATABASE IF EXISTS ryanzec;
Query OK, 1 row affected (0.03 sec)
mysql> CREATE DATABASE ryanzec;
Query OK, 1 row affected (0.00 sec)
mysql> USE ryanzec
Database changed
mysql> CREATE TABLE mytable
-> (
-> id1 INT NOT NULL,
-> id2 INT NOT NULL,
-> mapTypeId INT NOT NULL,
-> primary key (id1,id2)
-> );
Query OK, 0 rows affected (0.10 sec)
mysql> DELIMITER $$
mysql> CREATE TRIGGER mytable_bi BEFORE INSERT ON mytable
-> FOR EACH ROW
-> BEGIN
-> DECLARE sum INT;
-> SET sum = NEW.id1 + NEW.id2;
-> SET NEW.id1 = (NEW.id1 + NEW.id2 - ABS(NEW.id1 - NEW.id2)) / 2;
-> SET NEW.id2 = sum - NEW.id1;
-> END $$
Query OK, 0 rows affected (0.10 sec)
mysql> DELIMITER ;
Watch What Happens When I Insert the Rows:
mysql> INSERT INTO mytable VALUES (1,2,3);
Query OK, 1 row affected (0.06 sec)
mysql> INSERT INTO mytable VALUES (2,1,3);
ERROR 1062 (23000): Duplicate entry '1-2' for key 'PRIMARY'
mysql> INSERT INTO mytable VALUES (5,4,6);
Query OK, 1 row affected (0.07 sec)
mysql> INSERT INTO mytable VALUES (4,5,6);
ERROR 1062 (23000): Duplicate entry '4-5' for key 'PRIMARY'
mysql> SELECT * FROM mytable;
+-----+-----+-----------+
| id1 | id2 | mapTypeId |
+-----+-----+-----------+
| 1 | 2 | 3 |
| 4 | 5 | 6 |
+-----+-----+-----------+
2 rows in set (0.00 sec)
mysql>
Now, no matter what order id1 and id2 are entered, id1 will always be less than or equal to id2
This may not be contextually what you want because id1 and id2 are unique identifiers.
Best Answer
The number of polynomials is the number of distinct
graph_id
values. (You probably have a separate table for graphs; in this case, theSELECT DISTINCT
subqueries can be replaced withSELECT graph_id FROM graph
.)To count unique polynomials, we exclude any that are duplicates.
A polynomial is a duplicate if there exists any other polynomial with a smaller ID (the smallest ID would be the non-duplicate) and with the same coefficients.
Two polynomials have the same coefficients if there are not any differences in the possible x/y/coefficient combinations for both, i.e., for each row of one polynomial, the same row must exist for the other polynomial. In other words, there must not exist any row that does not have a match for the other polynomial.
And now that we have the description in the language of set theory, we can translate it directly into SQL. (I've used compound SELECTs for the innermost comparisons to avoid yet another level of negated subquery lookups.)
If computing the count dynamically is too slow, you could try to create a temporary table that contains the data in a format that is easier to count: