I'm trying to SELECT, and get a unique result set, from a MySQL database, as shown below. My problem is, I think, I don't understand LEFT Joins well enough. Or, maybe I need to use a different Join approach.
Here's a description of the database.
tbAdult (Adults) have x number of tbchild (Children) , and uses a cross-ref table called tbadultchildxref. This table has an f-key to both Adult and Child. I have to use an x-ref table, because there's a many-to-many relationship between these two tables, and there's other data that's keep in the x-ref, which I have removed for simplicity.
In turn, each Child belongs to a Program (tblprogram).
Each Program has x number of Cameras (tblCamera). Again, I have to use an x-ref table between tblProgram and tblCamera due to a many-to-many relationship, and other reasons.
What I am trying to get at, is a unique list of Cameras for a given Parent.
For example, Parent 675 has three children, Child ID's 789,788, and 789. Those three children, in turn, belong to Program ID's 4, 5, and 6.
Program ID 4 has Camera ID's 1,2,3
Program ID 5 has Camera ID's 4,5,6
Program ID 6 has Camera ID's 1,6,7,8
What I would like the result set to be is 1,2,3,4,5,6,7,8
I have tried different combinations of SELECT DISTINCT, LEFT JOINS on the various x-ref tables, etc. but I just can't seem to get it.
My other problem, along the way, is I need to check the "Active" fields in Adult, Child, and Program to equal = 1 (true) for the result set.
Thanks in advance.
CREATE TABLE `tbladult` (
`pkAdultID` int(11) NOT NULL AUTO_INCREMENT,
`fldAdultActive` tinyint(1) DEFAULT '1',
`fldAdultLogin` varchar(30) DEFAULT NULL,
`fldAdultPassword` varchar(45) DEFAULT NULL,
`fldAdultFirstName` varchar(60) DEFAULT NULL,
`fldAdultLastName` varchar(60) DEFAULT NULL,
PRIMARY KEY (`pkAdultID`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;
/*Table structure for table `tblchild` */
CREATE TABLE `tblchild` (
`pkChildID` int(11) NOT NULL AUTO_INCREMENT,
`fldChildActive` tinyint(4) DEFAULT NULL,
`fldChildFirstName` varchar(45) DEFAULT NULL,
`fldChildLastName` varchar(45) DEFAULT NULL,
`fkChildProgram` int(1) DEFAULT NULL,
PRIMARY KEY (`pkChildID`),
KEY `FK_tblchild` (`fkChildProgram`),
CONSTRAINT `FK_tblchild` FOREIGN KEY (`fkChildProgram`) REFERENCES `tblprogram` (`pkProgramID`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
/*Table structure for table `tbladultchildxref` */
CREATE TABLE `tbladultchildxref` (
`pkAdultChildxRefID` int(11) NOT NULL AUTO_INCREMENT,
`fldAdultChildxRefActive` tinyint(1) DEFAULT '1',
`fkAdultID` int(11) DEFAULT NULL,
`fkChildID` int(11) DEFAULT NULL,
PRIMARY KEY (`pkAdultChildxRefID`),
KEY `FK_tbladultchildxref` (`fkAdultID`),
KEY `FK_tbladultchildxref2` (`fkChildID`),
CONSTRAINT `FK_tbladultchildxref` FOREIGN KEY (`fkAdultID`) REFERENCES `tbladult` (`pkAdultID`),
CONSTRAINT `FK_tbladultchildxref2` FOREIGN KEY (`fkChildID`) REFERENCES `tblchild` (`pkChildID`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
/*Table structure for table `tblprogram` */
CREATE TABLE `tblprogram` (
`pkProgramID` int(11) NOT NULL AUTO_INCREMENT,
`fldProgamActive` tinyint(1) DEFAULT '1',
`fldProgramName` varchar(50) DEFAULT NULL,
PRIMARY KEY (`pkProgramID`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=latin1;
/*Table structure for table `tblcamera` */
CREATE TABLE `tblcamera` (
`pkCameraID` int(11) NOT NULL AUTO_INCREMENT,
`fldCameraName` varchar(50) DEFAULT NULL,
`fldCameralocation` varchar(50) DEFAULT NULL,
`fldCameraURL` varchar(250) DEFAULT NULL,
PRIMARY KEY (`pkCameraID`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;
/*Table structure for table `tblprogramcameraxref` */
CREATE TABLE `tblprogramcameraxref` (
`pkProgramCameraXrefID` int(11) NOT NULL AUTO_INCREMENT,
`fkProgramID` int(11) DEFAULT NULL,
`fkCameraID` int(11) DEFAULT NULL,
PRIMARY KEY (`pkProgramCameraXrefID`),
KEY `FK_tblprogramcameraxref` (`fkProgramID`),
KEY `FK_camerasforprograms` (`fkCameraID`),
CONSTRAINT `FK_camerasforprograms` FOREIGN KEY (`fkCameraID`) REFERENCES `tblcamera` (`pkCameraID`),
CONSTRAINT `FK_tblprogramcameraxref` FOREIGN KEY (`fkProgramID`) REFERENCES `tblprogram` (`pkProgramID`)
No LEFT JOINs necessary:
SELECT DISTINCT tblprogramcameraxref.fkcameraid
FROM tblprogramcameraxref
JOIN tblprogram ON tblprogramcameraxref.fkprogramid = tblprogram.pkprogramid
AND tblprobram.fldProgramActive = 1
JOIN tblchild ON tblprogramcameraxref.fkprogramid = tblchild.fkchildprogram
AND tblchild.fldChildActive = 1
JOIN tbladultchildxref ON tblchild.pkchildid = tbladultchildxref.fkchildid
AND tbladultchildxref.fldAdultChildxRefActive = 1
WHERE tbladultchildxref.fkadultid = 675
Also, you may want to check the fkChildProgram int(1) DEFAULT NULL, in tblchild - the column it references is defined as int(11)
At this point you shouldn't really need to check if Adult is active (since that's the search criteria you started with), but if you must - just add this to the end of the join list:
JOIN tbladult ON tbladultchildxref.fkadultid = tbladult.pkadultid
AND tbladult.fldAdultActive = 1
It is a long description. If I have understood the question correctly this query should help you -
SELECT DISTINCT pcref.fkCameraID
FROM tbladult adult,
tblchild child,
tbladultchildxref acref,
tblprogram prog,
tblcamera camera,
tblprogramcameraxref pcref
WHERE adult.pkAdultID = 675
AND adult.fldAdultActive = TRUE
AND adult.pkAdultID = acref.fkAdultID
AND acref.fkChildID = child.pkChildID
AND child.fldChildActive = TRUE
AND child.fkChildProgram = prog.pkProgramID
AND prog.fldProgamActive = TRUE
AND prog.pkProgramID = pcref.fkProgramID
Related
I am creating an inventory management app in node.js that uses MySQL as a database. I have a weak entity “rental_item” that holds the items in a particualr rental. The issue is that the rental may not come back all at once so I need a way of marking the “rental_returned” boolean in the rental table true only when all of the “item_returned” entires are true.
Here is my table structure:
CREATE TABLE `rental` (
`rental_id` int NOT NULL AUTO_INCREMENT,
`renter_id` int NOT NULL,
`date_in` date NOT NULL,
`date_out` date NOT NULL,
`sig_path` varchar(50) NOT NULL,
`doc_path` varchar(50) NOT NULL,
`col_name` varchar(50) NOT NULL,
`col_path` varchar(50) NOT NULL,
`cost` decimal(15,2) NOT NULL,
`rental_returned` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`rental_id`),
UNIQUE KEY `doc_path` (`doc_path`),
UNIQUE KEY `col_path` (`col_path`),
UNIQUE KEY `sig_path` (`sig_path`),
KEY `renter_key` (`renter_id`),
CONSTRAINT `renter_key` FOREIGN KEY (`renter_id`) REFERENCES `renter` (`renter_id`)
)
CREATE TABLE `rental_item` (
`rental_id` int NOT NULL,
`i_ID` varchar(20) NOT NULL,
`item_returned` tinyint(1) NOT NULL DEFAULT '0',
KEY `rental_key` (`rental_id`),
KEY `rental_item_key` (`i_ID`),
CONSTRAINT `rental_item_key` FOREIGN KEY (`i_ID`) REFERENCES `item` (`i_ID`),
CONSTRAINT `rental_key` FOREIGN KEY (`rental_id`) REFERENCES `rental` (`rental_id`) ON DELETE CASCADE
)
I am currently doing this through the mysql2 node.js module and just checking for all the values of a given rental_id. I then found out about triggers and thought this way could be better. I fiddled round with things like this Trigger with table join, but couldn’t wrap my head around how to get the rental_id of the entry that was updated from rental_item, then check that all entires in rental_item with that id have item_returned = 1, and finally update the rental table to show that all the items/the complete rental has been returned.
I understand that this sould be an update after trigger on rental_item but dont know how to handle the conditionals or loops needed.
Use NEW.rental_id to get the ID of the row that was updated.
CREATE TRIGGER rental_returned AFTER UPDATE ON rental_item
FOR EACH ROW
UPDATE rental
SET rental_returned = (
NOT EXISTS (
SELECT *
FROM rental_item
WHERE rental_id = NEW.rental_id
AND item_returned = 0))
WHERE rental_id = NEW.rental_id
I have 2 MySQL tables. One is pastsergicalhistory_type and the other one is pastsurgicalhistory
Below is pastsergicalhistory_type
CREATE TABLE `pastsergicalhistory_type` (
`idPastSergicalHistory_Type` int(11) NOT NULL AUTO_INCREMENT,
`idUser` int(11) DEFAULT NULL,
`Name` varchar(45) NOT NULL,
PRIMARY KEY (`idPastSergicalHistory_Type`),
KEY `fk_PastSergicalHistory_Type_User1_idx` (`idUser`),
CONSTRAINT `fk_PastSergicalHistory_Type_User1` FOREIGN KEY (`idUser`) REFERENCES `user` (`idUser`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8
Below is pastsurgicalhistory
CREATE TABLE `pastsurgicalhistory` (
`idPastSurgicalHistory` int(11) NOT NULL AUTO_INCREMENT,
`idPatient` int(11) NOT NULL,
`idPastSergicalHistory_Type` int(11) NOT NULL,
`Comment` varchar(45) DEFAULT NULL,
`ActiveStatus` tinyint(1) NOT NULL,
`LastUpdated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`idPastSurgicalHistory`),
KEY `fk_PastSurgicalHistory_Patient1_idx` (`idPatient`),
KEY `fk_PastSurgicalHistory_PastSergicalHistory_Type1_idx` (`idPastSergicalHistory_Type`),
CONSTRAINT `fk_PastSurgicalHistory_PastSergicalHistory_Type1` FOREIGN KEY (`idPastSergicalHistory_Type`) REFERENCES `pastsergicalhistory_type` (`idPastSergicalHistory_Type`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_PastSurgicalHistory_Patient1` FOREIGN KEY (`idPatient`) REFERENCES `patient` (`idPatient`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8
Now my requirement is as this, I will explain it in point form.
Get all the data from pastsergicalhistory_type where idUser is NULL or idUser is 1.
Get all the data from pastsurgicalhistory where idPatient is 2.
as you can see, the foreign key of pastsurgicalhistory is the primary key of pastsergicalhistory_type.
I tried the below query, but it gave me the wrong results. It only displayed what is available in pastsurgicalhistory. The data in pastsergicalhistory_type (which follows the condition in point 1) which is not in pastsurgicalhistory is not displayed.
SELECT pastsergicalhistory_type.*,
pastsurgicalhistory.*
FROM pastsergicalhistory_type
LEFT JOIN pastsurgicalhistory ON pastsurgicalhistory.`idPastSergicalHistory_Type` = pastsergicalhistory_type.`idPastSergicalHistory_Type`
WHERE pastsergicalhistory_type.idUser = NULL OR pastsergicalhistory_type.idUser=1 AND pastsurgicalhistory.idPatient=2
So, how can I solve this problem?
EDIT
If I use the AND pastsurgicalhistory.idPatient=2 in my where clause, it actually filters the "entire" result set. This will give me results where idPatient is related to 2. But as I mentioned, I need data which is not available in pastsurgicalhistory table as well.
Try
SELECT pastsergicalhistory_type.*,
pastsurgicalhistory.*
FROM pastsergicalhistory_type
LEFT JOIN pastsurgicalhistory ON
(pastsurgicalhistory.`idPastSergicalHistory_Type` =
pastsergicalhistory_type.`idPastSergicalHistory_Type` and
pastsurgicalhistory.idPatient=2)
WHERE (pastsergicalhistory_type.idUser = NULL OR
pastsergicalhistory_type.idUser=1) ;
Move pastsurgicalhistory.idPatient=2 to join condition
SELECT pastsergicalhistory_type.*,
pastsurgicalhistory.*
FROM pastsergicalhistory_type
LEFT JOIN pastsurgicalhistory ON pastsurgicalhistory.`idPastSergicalHistory_Type` = pastsergicalhistory_type.`idPastSergicalHistory_Type`
AND pastsurgicalhistory.idPatient=2
WHERE pastsergicalhistory_type.idUser IS NULL OR pastsergicalhistory_type.idUser=1
Use paraenthises?
WHERE pastsergicalhistory_type.idUser = NULL OR pastsergicalhistory_type.idUser=1 AND pastsurgicalhistory.idPatient=2
I belive would return results where idUser is 1 and idPatient is 2 or iduser is null
Try this:
WHERE (pastsergicalhistory_type.idUser = NULL OR pastsergicalhistory_type.idUser=1) AND pastsurgicalhistory.idPatient=2
If I understand you correctly?
SELECT pastsergicalhistory_type.*,
pastsurgicalhistory.*
FROM pastsergicalhistory_type
RIGHT JOIN pastsurgicalhistory ON pastsurgicalhistory.`idPastSergicalHistory_Type` = pastsergicalhistory_type.`idPastSergicalHistory_Type`
WHERE (pastsergicalhistory_type.idUser = NULL OR pastsergicalhistory_type.idUser=1) AND pastsurgicalhistory.idPatient=2
Even if it works without parenthesis for you, I would say it's better to use to make it more readable.
I am trying to optimize the execution of a MYSQL query that joins two tables as follows:
CREATE TABLE `CPP` (
`RecordEntryType` varchar(7) NOT NULL default '',
`PositionNumber` mediumint(9) NOT NULL default '0',
`FundId` smallint(6) default NULL,
`QuantityHeld` decimal(14,2) default NULL,
`MarketValue` decimal(14,2) default NULL,
`PeriodBeginDate` date default NULL,
`PeriodEndDate` date NOT NULL default '0000-00-00',
PRIMARY KEY (`PositionNumber`,`PeriodEndDate`,`RecordEntryType`),
KEY `Index1` (`FundId`,`PeriodBeginDate`,`PeriodEndDate`),
KEY `FundId_idx` (`FundId`),
KEY `PeriodBeginDate_idx` (`PeriodBeginDate`),
KEY `PeriodEndDate_idx` (`PeriodEndDate`),
KEY `PositionNumber_id` (`PositionNumber`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `classification_entity_map` (
`entity_id` varchar(32) NOT NULL,
`entity_type` varchar(32) NOT NULL,
`scheme_id` int(11) NOT NULL,
`class_id` varchar(24) NOT NULL,
PRIMARY KEY (`entity_id`,`entity_type`,`scheme_id`),
KEY `fk_classification_entity_map_1` (`scheme_id`),
KEY `fk_class` (`class_id`),
CONSTRAINT `fk_class` FOREIGN KEY (`class_id`) REFERENCES `classification_hierarchy` (`external_id`),
CONSTRAINT `fk_scheme` FOREIGN KEY (`scheme_id`) REFERENCES `classification_schemes` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
select cpp.*, cem.class_id from cpp
LEFT JOIN classification_entity_map cem
ON cem.entity_id = cpp.PositionNumber and cem.entity_type = 'Security'
AND cem.scheme_id = 9901
WHERE cpp.RecordEntryType = 'CURRENT'
AND ( cpp.MarketValue != 0 OR cpp.QuantityHeld != 0 )
AND FundId = 28
AND cpp.PeriodEndDate = '2013-09-30';
The issue is that the query takes longer than expected in mysql workbench (9.4 secs) as it is using the fk_classification_entity_map_1 index rather than the primary index on classification_entity_map table. cpp has 626,648 rows and cem has 63,487 rows.
I suspect that the issue has to do with the datatypes of cem.entity_id & cpp.PositionNumber but I am not sure as they cannot be changed. Please help. I can upload the explain output if that is helpful.
More Info: Changing the join to convert(cpp.PositionNumber, char(32)) as below does not help as the time goes up to 10 secs:
ON cem.entity_id = convert(cpp.PositionNumber, char(32)) and cem.entity_type = 'Security'
AND cem.scheme_id = 9901
The explain output for the query without convert is below and sees the PRIMARY as possible (but not in the query with convert):
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE cpp index_merge Index1,FundId_idx,PeriodEndDate_idx FundId_idx,PeriodEndDate_idx 3,3 402 Using intersect(FundId_idx,PeriodEndDate_idx); Using where
1 SIMPLE cem ref PRIMARY,fk_classification_entity_map_1 fk_classification_entity_map_1 4 const 24100
I want to subtract between two rows of different table:
I have created a view called leave_taken and table called leave_balance.
I want this result from both table:
leave_taken.COUNT(*) - leave_balance.balance
and group by leave_type_id_leave_type
Code of both table
-----------------View Leave_Taken-----------
CREATE ALGORITHM = UNDEFINED DEFINER=`1`#`localhost` SQL SECURITY DEFINER
VIEW `leave_taken`
AS
select
`leave`.`staff_leave_application_staff_id_staff` AS `staff_leave_application_staff_id_staff`,
`leave`.`leave_type_id_leave_type` AS `leave_type_id_leave_type`,
count(0) AS `COUNT(*)`
from
(
`leave`
join `staff` on((`staff`.`id_staff` = `leave`.`staff_leave_application_staff_id_staff`))
)
where (`leave`.`active` = 1)
group by `leave`.`leave_type_id_leave_type`;
----------------Table leave_balance----------
CREATE TABLE IF NOT EXISTS `leave_balance` (
`id_leave_balance` int(11) NOT NULL AUTO_INCREMENT,
`staff_id_staff` int(11) NOT NULL,
`leave_type_id_leave_type` int(11) NOT NULL,
`balance` int(3) NOT NULL,
`date_added` date NOT NULL,
PRIMARY KEY (`id_leave_balance`),
UNIQUE KEY `id_leave_balance_UNIQUE` (`id_leave_balance`),
KEY `fk_leave_balance_staff1` (`staff_id_staff`),
KEY `fk_leave_balance_leave_type1` (`leave_type_id_leave_type`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
------- Table leave ----------
CREATE TABLE IF NOT EXISTS `leave` (
`id_leave` int(11) NOT NULL AUTO_INCREMENT,
`staff_leave_application_id_staff_leave_application` int(11) NOT NULL,
`staff_leave_application_staff_id_staff` int(11) NOT NULL,
`leave_type_id_leave_type` int(11) NOT NULL,
`date` date NOT NULL,
`active` int(11) NOT NULL DEFAULT '1',
`date_updated` date NOT NULL,
PRIMARY KEY (`id_leave`,`staff_leave_application_id_staff_leave_application`,`staff_leave_application_staff_id_staff`),
KEY `fk_table1_leave_type1` (`leave_type_id_leave_type`),
KEY `fk_table1_staff_leave_application1` (`staff_leave_application_id_staff_leave_application`,`staff_leave_application_staff_id_staff`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=32 ;
Well, I still don't think you've provided enough information. It would be very helpful to have some sample data and your expected output (in tabular format). That said, I may have something you can start working with. This query finds all staff members, calculates their current leave (grouped by type), and determines the difference between that and their balance by leave type. Take a look at it, and more importantly (perhaps) the sqlfiddle here that I used which has the sample data in it (very important to determining if this is the correct path for your data).
SELECT
staff.id_staff,
staff.name,
COUNT(`leave`.id_leave) AS leave_count,
leave_balance.balance,
(COUNT(`leave`.id_leave) - leave_balance.balance) AS leave_difference,
`leave`.leave_type_id_leave_type AS leave_type
FROM
staff
JOIN `leave` ON staff.id_staff = `leave`.staff_leave_application_staff_id_staff
JOIN leave_balance ON
(
staff.id_staff = leave_balance.staff_id_staff
AND `leave`.leave_type_id_leave_type = leave_balance.leave_type_id_leave_type
)
WHERE
`leave`.active = 1
GROUP BY
staff.id_staff, leave_type;
Good luck!
I have the following tables; which will be holding information about various types of articles.
I need some help with coming up with a proper schema for this.
Tables are:
CREATE TABLE IF NOT EXISTS `math_articles` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` char(250) NOT NULL,
`body` text,
PRIMARY KEY (`id`),
UNIQUE KEY `title` (`title`)
)
CREATE TABLE IF NOT EXISTS `news_articles` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` char(250) NOT NULL,
`body` text,
PRIMARY KEY (`id`),
UNIQUE KEY `title` (`title`)
)
CREATE TABLE IF NOT EXISTS `other_articles` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` char(250) NOT NULL,
`body` text,
PRIMARY KEY (`id`),
UNIQUE KEY `title` (`title`)
)
CREATE TABLE IF NOT EXISTS `references` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`article_from_table_name` text NOT NULL,
`from_id` int(11) NOT NULL,
`article_to_table_name` text NOT NULL,
`to_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
)
inserting test data:
INSERT INTO `TEST`.`math_articles` (
`id` ,
`title` ,
`body`
)
VALUES (
NULL , 'fibonacci sequences', 'fib sequences are: 0,1,1,2,3,5...also see article Leonardo of Pisa'
);
Since this math_articles.title = 'fibonacci sequences' mentions that article 'Leonardo of Pisa' my program will insert in to other_articles table the following data:
INSERT INTO `TEST`.`other_articles` (
`id` ,
`title` ,
`body`
)
VALUES (
NULL , 'Leonardo of Pisa', 'Leonardo of Pisa also known as Leonardo of Pisa, Leonardo Pisano, Leonardo Bonacci, Leonardo Fibonacci, or, most commonly, simply Fibonacci, was.....'
);
The schema problem regarding table references
Since the table other_articles.title = 'Leonardo of Pisa' was referenced in the table math_articles.title = 'fibonacci sequences' i was to save this reference in the references table as follows:
not sure/problem insert into references table
INSERT INTO `TEST`.`references`
(`id`, `article_from_table_name`, `from_id`, `article_to_table_name`, `to_id`)
VALUES
(NULL, 'math_articles', '1', 'other_articles', '1');
Whats the best way of going about saving these references?
My issues with the references table schema!
The data type of the two columns article_from_table_name and article_to_table_name is text but they are actual tables in my database.
from_id and to_id should be forign keys of their prespective tables as
from_id = article_from_table_name.id and to_id = article_to_table_name.id
I don't know how to define this in the schema.
what if i delete the article math_articles.title = 'fibonacci sequences' then the references table to also be updated, I know I should use some sort of "ON DELETE CASCADE' trigger.
Regards
Your database design is causing most of your issues here. Your three articles tables, maths, news and other should all be the same table with a type column to distinguish between the different types. Then it will be straight forward to set up a references table that contains two foreign keys to the articles table, one for the source article and one for the reference article.
I usually manage referential integrity in the application itself rather than in the database layer so that all your business logic is in one place. So if you delete an article then any reference entries should be deleted by the application itself.
Hope that helps!