Having trouble summing columns in SQL Server joined view - oracle-apex

Moi guys, Matt here. I'm having trouble with a relatively complicated view. I have a parts and service table that each have unique identifiers for a given part/service. I'm trying to link these to a service invoice table and subsequent view as a M:N relationship, so I've set up intermediary relational tables, with both the invoice number (invoice primary key) and part/service number (part/service primary key) as the combined primary key. Here's my code for the whole relationship and view:
CREATE TABLE service_invoice
( servinv_Num VARCHAR2(10) CONSTRAINT serv_snum_PK PRIMARY KEY,
servinv_EmpID NUMBER(6) CONSTRAINT serv_empnum_FK REFERENCES employee(empID),
servinv_CustID NUMBER(6) CONSTRAINT serv_custid_FK REFERENCES customer(custID),
servinv_VIN VARCHAR2(25) CONSTRAINT serv_VIN_FK REFERENCES vehicle(vehicle_vin),
servinv_Terms VARCHAR2(6) CONSTRAINT serv_trms_NN NOT NULL,
servinv_Date DATE );
CREATE TABLE Parts
( PartID VARCHAR2(10) CONSTRAINT Part_PartID_PK PRIMARY KEY,
PartDesc VARCHAR2(50) CONSTRAINT Part_PartDesc_NN NOT NULL,
PartCharge NUMBER(4,2) CONSTRAINT Part_PartCharge_NN NOT NULL );
CREATE TABLE Service
( ServiceID VARCHAR2(10) CONSTRAINT Serv_ServID_PK PRIMARY KEY,
ServDesc VARCHAR2(50) CONSTRAINT Serv_ServName_NN NOT NULL,
ServCharge NUMBER(4,2) CONSTRAINT Serv_ServCharge_NN NOT NULL );
CREATE TABLE Serv_SI_Rel
( SI_num VARCHAR2(10) CONSTRAINT ServSI_SInum_FK REFERENCES service_invoice(servinv_Num),
ServiceID VARCHAR2(10) CONSTRAINT ServSI_ServID_FK REFERENCES Service(ServiceID),
CONSTRAINT ServSI_SInum_ServID_PK PRIMARY KEY(SI_num, ServiceID) );
CREATE TABLE Parts_SI_Rel
( SI_num VARCHAR2(10) CONSTRAINT PartSI_SInum_FK REFERENCES service_invoice(servinv_Num),
PartID VARCHAR2(10) CONSTRAINT PartSI_PartID_FK REFERENCES Parts(PartID),
CONSTRAINT PartSI_SInum_PartID_PK PRIMARY KEY(SI_num, PartID) );
CREATE OR REPLACE VIEW ServiceInvoiceDoc
AS
(
SELECT si.servinv_Num, si.servinv_Date, si.servinv_Terms,
es.empName,
sc.custName, sc.custHouse, sc.custCity,
sc.custState, sc.custZIP, sc.custPhone, sc.custEmail,
sv.vehicle_VIN, sv.vehicle_mileage,
srel.ServiceID,
prel.PartID,
s.ServDesc, s.ServCharge,
p.PartDesc, p.PartCharge,
SUM(s.ServCharge) TotalServCharges,
SUM(p.PartCharge) TotalPartsCharges,
( SUM(s.ServCharge)+SUM(p.PartCharge) ) SubTotalCharges,
( SUM(s.ServCharge)+SUM(p.PartCharge) )*0.0825 Taxes,
( SUM(s.ServCharge)+SUM(p.PartCharge) )*1.0825 TotalCharges
FROM service_invoice si
JOIN employee es
ON (es.empID = si.servinv_EmpID)
JOIN customer sc
ON (sc.custID = si.servinv_CustID)
JOIN vehicle sv
ON (sv.vehicle_VIN = si.servinv_VIN)
LEFT OUTER JOIN Serv_SI_Rel srel
ON (srel.SI_Num = si.servinv_Num)
LEFT OUTER JOIN Parts_SI_Rel prel
ON (prel.SI_num = si.servinv_Num)
JOIN Parts p
ON (prel.PartID = p.PartID)
JOIN Service s
ON (srel.ServiceID = s.ServiceID) );
The error I get has to do with summing the individual parts and service charges in the M:N relationship. Here's the error code from the run:
ORA-00937: not a single-group group function
I've tried fixing with a group by command, but the grouping identifier (service invoice) isn't included on the part or service tables, and the joins don't seem to link these up for a group. e.g. I tried calling GROUP BY si.servinv_Num
Can this be resolved at all or is it completely wrong? I have the option of dropping the M:N relationship as a 1:M and simply making a separate invoice for each part/service charge, but I would prefer to keep it compact and professional.
Any help would be greatly appreciated. Thank you so much for your time!

a) wrong tag
b) I'd imagine you would need to list all columns in group by clause that aren't aggregated, as per Oracle
...
group by si.servinv_Num, si.servinv_Date, si.servinv_Terms,
es.empName,
sc.custName, sc.custHouse, sc.custCity,
sc.custState, sc.custZIP, sc.custPhone, sc.custEmail,
sv.vehicle_VIN, sv.vehicle_mileage,
srel.ServiceID,
prel.PartID,
s.ServDesc, s.ServCharge,
p.PartDesc, p.PartCharge

Related

Why MySQL workbench is making all my foreign keys unique?

I've created a MySQL Model with a few tables, some of them with fk's to another table. I usually export the SQL from MySQL Model to my database using the "Forward Engineer SQL CREATE Script" inside File -> Export -> Forward Engineer SQL CREATE Script. The problem here is that when I generate the creation script, all my fk's become unique. I didn't check UQ option in MySQL Model but it creates a script with unique fk's anyway, so, I need to change the SQL file generated and remove all the unwanted uniques. Anyone has a clue why this is happening?
Generated script:
CREATE TABLE IF NOT EXISTS `u514786799_detranleiloes`.`Lotes` (
`createdAt` DATE NOT NULL,
`updatedAt` DATE NOT NULL,
`id` INT UNIQUE NOT NULL AUTO_INCREMENT,
`LeiloesId` INT UNIQUE NOT NULL,
`conservado` TINYINT NULL,
`numero` INT NOT NULL,
`CRDsId` INT UNIQUE NULL,
PRIMARY KEY (`id`),
INDEX `fk_Lotes_Leiloes_idx` (`LeiloesId` ASC),
INDEX `fk_Lotes_CRDs1_idx` (`CRDsId` ASC),
CONSTRAINT `fk_Lotes_Leiloes`
FOREIGN KEY (`LeiloesId`)
REFERENCES `u514786799_detranleiloes`.`Leiloes` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_Lotes_CRDs1`
FOREIGN KEY (`CRDsId`)
REFERENCES `u514786799_detranleiloes`.`CRDs` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
AUTO_INCREMENT = 1;

PSQL asking for Unique constraint?

So I am trying to create the following tables and psql will not let me create these tables unless C_Subject is given a UNIQUE constraint in the Curriculum_Subjects table.
CREATE TABLE IF NOT EXISTS Curriculum(
CID SERIAL NOT NULL,
Curriculum_Name VARCHAR(100),
Classes_Needed INTEGER,
Classes_Total INTEGER,
PRIMARY KEY(CID)
);
CREATE TABLE IF NOT EXISTS Class_Subjects(
C_Subject SERIAL NOT NULL,
Class_Subject VARCHAR(100),
PRIMARY KEY(C_Subject)
);
CREATE TABLE IF NOT EXISTS Curriculum_Subjects(
C_Subject SERIAL UNIQUE NOT NULL REFERENCES Class_Subjects(C_Subject),
CID SERIAL NOT NULL REFERENCES Curriculum(CID),
PRIMARY KEY(C_Subject, CID)
);
However the way I want my database to work is that one C_Subject can be in many curriculum. So below inserting the same C_Subject into two different curriculum should be valid. CID being the identifier for a different curriculum.
INSERT INTO Curriculum_Subjects(C_Subject, CID)
VALUES(2,1);
INSERT INTO Curriculum_Subjects(C_Subject, CID)
VALUES(2,2);
psql won't let this insert happen because C_Subject has a UNIQUE constraint. Why does C_Subject need to be UNIQUE in Curriculum_Subjects if it belongs to the composite key, PRIMARY KEY(C_Subject, CID) ? Can this insert be achievable?

Complex SQL syntax

I have a game, and in the database I'm saving the user actions by date & time.
CREATE TABLE user_actions
(
aId BIGSERIAL PRIMARY KEY NOT NULL,
userId BIGINT NOT NULL REFERENCES users(uId) DEFERRABLE INITIALLY DEFERRED,
aDate TIMESTAMP without time zone DEFAULT now(),
aType INTEGER NOT NULL DEFAULT 0
);
My users are identified with email
CREATE TABLE users(
uId BIGSERIAL PRIMARY KEY NOT NULL,
uName VARCHAR (50) NOT NULL,
uEmail VARCHAR (75) UNIQUE NULL
);
and each day new prizes are added each day has a different number of prizes
CREATE TABLE prizes(
pId BIGSERIAL PRIMARY KEY NOT NULL,
pDate TIMESTAMP without time zone DEFAULT now(),
pType INTEGER NULL
pSize INTEGER NULL
);
This query list the userId and his last action date, per user
select distinct userId, max(aDate) from user_actions GROUP BY userId order by userId;
I want to create a query that will count the number of prizes added since each user last action.
I'm running:
OS: Debian
DB: Postgresql
code: Django
I think I will use CTE though It has not been tested
WITH last_actions AS (
SELECT DISTINCT userId, MAX(aDate) as last_logged
FROM user_actions
GROUP BY userId ORDER BY userId)
SELECT a.userId, COUNT(b.pDate)
FROM last_actions a, prizes b
WHERE b.pDate >= a.last_logged
GROUP BY a.userId;

Trying to add foreign key in mysql with heidisql

I've been trying to add a foreign key to my table using heidisql and I keep getting the error 1452.
After reading around I made sure all my tables were running on InnoDB as well as checking that they had the same datatype and the only way I can add my key is if I drop all my data which I don't intend to do since I have spent quite a few hours on this.
here is my table create code:
CREATE TABLE `data` (
`ID` INT(10) NOT NULL AUTO_INCREMENT,
#bunch of random other columns stripped out
`Ability_1` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0',
#more stripped tables
`Extra_Info` SET('1','2','3','Final','Legendary') NOT NULL DEFAULT '1' COLLATE 'utf8_unicode_ci',
PRIMARY KEY (`ID`),
UNIQUE INDEX `ID` (`ID`)
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
AUTO_INCREMENT=650;
here is table 2
CREATE TABLE `ability` (
`ability_ID` SMALLINT(5) UNSIGNED NOT NULL AUTO_INCREMENT,
#stripped columns
`Name_English` VARCHAR(12) NOT NULL COLLATE 'utf8_unicode_ci',
PRIMARY KEY (`ability_ID`),
UNIQUE INDEX `ability_ID` (`ability_ID`)
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
AUTO_INCREMENT=165;
Finally here is the create code along with the error.
ALTER TABLE `data`
ADD CONSTRAINT `Ability_1` FOREIGN KEY (`Ability_1`) REFERENCES `ability` (`ability_ID`) ON UPDATE CASCADE ON DELETE CASCADE;
/* SQL Error (1452): Cannot add or update a child row: a foreign key constraint fails (`check`.`#sql-ec0_2`, CONSTRAINT `Ability_1` FOREIGN KEY (`Ability_1`) REFERENCES `ability` (`ability_ID`) ON DELETE CASCADE ON UPDATE CASCADE) */
If there is anything else I can provide please let me know this is really bothering me. I'm also using 5.5.27 - MySQL Community Server (GPL) that came with xampp installer.
If you are using HeidiSQL it is pretty easy.
Just see the image, click on the +Add to add foreign keys.
I prefer GUI way of creating tables and its attribute because it saves time and reduces errors.
I found it. Sorry everyone. The problem was that I had 0 as a default value for my fields while my original table had no value for 0.
Here is how you can do it ;
Create your Primary keys. For me this was straight forward so I won't post how to do that here
To create your FOREIGN KEYS you need to change the table / engine type for each table from MyIASM to InnoDb. To do this Select the table on the right hand side then select the OPTIONS tab on the right hand side and change the engine from MyIASM to InnoDb for every table.

Can't create table (errno: 150) InnoDB adding foreign key constraints

Really hate to use other people's time, but it seems the problem is just not going away.
I considered all recommendations at http://verysimple.com/2006/10/22/mysql-error-number-1005-cant-create-table-mydbsql-328_45frm-errno-150/ and at http://forums.mysql.com/read.php?22,19755,19755#msg-19755 but nothing.
hope that someone points to a stupid mistake.
here are the tables:
CREATE TABLE IF NOT EXISTS `shop`.`category` (
`id` INT(11) NOT NULL AUTO_INCREMENT ,
`category_id` INT(11) NOT NULL ,
`parent_id` INT(11) NULL DEFAULT '0' ,
`lang_id` INT(11) NOT NULL ,
...other columns...
PRIMARY KEY (`id`, `category_id`) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `shop`.`product_category` (
`category_id` INT(11) NOT NULL ,
`product_id` INT(11) NOT NULL ,
INDEX `fk_product_category_category1_zxc` (`category_id` ASC) ,
CONSTRAINT `fk_product_category_category1_zxc`
FOREIGN KEY (`category_id` )
REFERENCES `shop`.`category` (`category_id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_unicode_ci;
Error Code: 1005. Can't create table 'shop.product_category' (errno: 150)
You need an index on category_id in the category table (I see it's part of the primary key, but since it's the second column in the index, it can not be used). The field you are referencing in a foreign key always should be indexed.
In my case the issue was more like what was described in the first article you've linked to.
So I just had to make sure that:
Referenced Column is an index,
both Referencing Column and Referenced Column share the same type and length, i.e. e.g. both are INT(10),
both share the same not null, unsigned, zerofill etc. configuration.
both tables are InnoDB!
Here's the query template where Referencing Column is referencing_id and Referenced Column is referenced_id:
ALTER TABLE `db`.`referencing`
ADD CONSTRAINT `my_fk_idx`
FOREIGN KEY (`referencing_id`)
REFERENCES `db`.`referenced`(`referenced_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;
Update 2016-03-13: Ran into this problem again, ended up finding my own answer. This time it didn't help though. Turns out the other table was still set to MyISAM, as soon as I changed it to InnoDB everything worked.