missing right parantjesis, missing expression, error on subquery - sql

My database is for a rental centre with music CDs and videotapes.
create table cds (
id_cd varchar2(5) pk_cduri primary key,
artists varchar2(100) not null,
genre varchar2(20) not null,
release date not null,
constraint pk_cds primary key(id_cd)
);
create table replenishment(
id_ap varchar2(5) constraint pk_aprovizionari primary key,
id_cd varchar2(5),
quantity_cd number(5,2) default 0,
price_cd number(5,2) default 0,
id_cv varchar2(5),
cquantity_cv number(5,2) default 0,
price_cv number(5,2) default 0,
data_rep date default sysdate,
total_cost as (quantity_cd* price_cd+ quantity_cv* price_cv),
constraint fk_ap_cd foreign key (id_cd) references cds,
constraint fk_ap_cv foreign key (id_cv) references videotapes
);
When a customer with id_cust='c1' borrows the cd with id_cd='cd1', then bor_cd=1 and when the customer 'c1' returns the 'cd1' I have to insert value 1 in ret_cd.
create table bor_ret (
id int constraint pk_bor_ret primary key,
id_cust varchar2(5) not null,
id_cd varchar2(5),
bor_cd int default 0,
ret_cd int default 0,
id_cv varchar2(5),
bor_cv int default 0,
ret_cv int default 0,
data date default sysdate,
constraint fk_cd_imp foreign key (id_cd) references cds(id_cd),
constraint fk_cv_imp foreign key (id_cv) references videotapes(id_cv),
constraint fk_ab_imp foreign key (id_cust) references customers,
constraint ck_imp_cd_value_flag check (bor_cd in (1,0)),
constraint ck_imp_cv_value_flag check (bor_cv in (1,0)),
constraint ck_ret_cd_value_flag check (ret_cd in (1,0)),
constraint ck_ret_cv_value_flag check (ret_cv in (1,0))
);
I have to create a trigger (I don't know how to define it, but if someone knows, I will ask a new question to accept it's answer) that sets bor_cd=0 every time after I insert value 1 in ret_cd:
update bor_ret set bor_cd=0 where id_cust=(select id_cust from bor_ret where ret_cd=1);
Then I have to add a computed column to CDS that calculate the quantity of the last cd inserted:
the quantity of 'cd1' from CDS which has the id_cd=cd1 is equal with the quantity supplied from BOR_RET where id_cd=cd1.
So, I want to run this command:
alter table cds add quantity as(
select quantity_cd from replenishment b inner join cds a on a.id_cd=b.id_cd where b.id_cd=
(select id_cd from cds where rownum=1 order by id_cd desc) -
(select count(id_cd) from bor_ret d inner join cds c on c.id_cd=d.id_cd where d.id_cd=
(select id_cd from cds where rownum=1 order by id_cd desc) and d.bor_cd=1));
and I get this error: "missing expression".
If I Run only the query: select quantity_cd... I get the error:
"ERROR at line 2: ORA-00907: missing right paranthesis"
Or, better, how can I add this column as differences of:
select quantity_cd from replenishment where id_cd=(select max(id_cd) from cds) as A
select count(id_cd) from bor_ret where id_cd=(select max(id_cd) from cds) and bor_cd=1 as B
quantity = A-B;
This thread is for solving the problem with computed column, but if someone can explain me how to create the trigger too I will open a new thread for it.
Thank you guys in advance.

Please note 2nd right parenthesis in the last but one line.
select quantity_cd
from replenishment b
inner join cds a on a.id_cd=b.id_cd
where b.id_cd=
(select id_cd from cds where rownum=1 order by id_cd desc) -
(select count(id_cd) from bor_ret d inner join cds c on c.id_cd=d.id_cd where d.id_cd= (select id_cd from cds where rownum=1 order by id_cd desc)) /* <------ ===*/
and d.bor_cd=1)

Related

SQLite GROUP BY lowest price missing results

I've got a SQLite DB that houses basically a list of products and prices.
CREATE TABLE brand_list (
id INTEGER NOT NULL,
brand_name TEXT NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE product_list (
id INTEGER NOT NULL,
prod_generic VARCHAR NOT NULL,
prod_pretty VARCHAR NOT NULL,
PRIMARY KEY (id),
UNIQUE (prod_generic)
);
CREATE TABLE qty_list (
id INTEGER NOT NULL,
qty_initial VARCHAR NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE vendor_list (
id INTEGER NOT NULL,
vendor_name TEXT NOT NULL,
vendor_url VARCHAR NOT NULL, url_pretty varchar not null default 1, datacollect varchar not null default 'Y',
PRIMARY KEY (id)
);
CREATE TABLE listing (
id INTEGER NOT NULL,
brand_id INTEGER,
qty_id INTEGER,
vendor_id INTEGER,
prod_id INTEGER,
qty_actual INTEGER,
price INTEGER,
unit_price FLOAT,
timestamp VARCHAR(255),
sale INTEGER DEFAULT 0 NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY(brand_id) REFERENCES brand_list (id),
FOREIGN KEY(prod_id) REFERENCES product_list (id),
FOREIGN KEY(qty_id) REFERENCES qty_list (id),
FOREIGN KEY(vendor_id) REFERENCES vendor_list (id)
I pull a query looking at the listing table with the goal of grabbing the lowest price and listing all of the relevant information for end users (ie brands, products, qty, price, when it was pulled, where it was pulled from).
select qty_initial, qty_actual, price, MIN(unit_price), brand_name, prod_pretty, sale, timestamp, vendor_name from listing left join brand_list on listing.brand_id = brand_list.id left join product_list on listing.prod_id = product_list.id left join vendor_list on listing.vendor_id = vendor_list.id left join qty_list on listing.qty_id = qty_list.id group by prod_pretty order by brand_name, prod_pretty
What I'm seeing is that most of the data is showing up but not all of the data is showing up. And it doesn't seem consistent - but one brand might show seven out of eight entries, another brand might have everything.
The interesting part is that if I add a WHERE clause just prior to the group by and specify a brand that I know is missing entries in the original output, I'll get all of the expected output for that brand.
This isn't my world - I'm just hacking something together for my own fun. I'm certain I'm missing something fundamental here and it's likely around the GROUP BY. Any direction would be great - even a way to rethink how I'm doing this to get to where I want to be in a simpler manner.
Your query is malformed -- although SQLite does accept it. The GROUP BY columns are inconsistent with the SELECT list.
Instead, use window functions:
select qty_initial, qty_actual, price, unit_price, brand_name, prod_pretty, sale, timestamp, vendor_name
from (select qty_initial, qty_actual, price, unit_price, brand_name, prod_pretty, sale, timestamp, vendor_name,
row_number() over (partition by prod_pretty order by unit_price) as seqnum
from listing left join
brand_list
on listing.brand_id = brand_list.id left join
product_list
on listing.prod_id = product_list.id left join
vendor_list
on listing.vendor_id = vendor_list.id left join
qty_list
on listing.qty_id = qty_list.id
group by prod_pretty
) p
where seqnum = 1
order by brand_name, prod_pretty

How to create constraint on attribute in table A which depends on attribute in table B?

I am trying to implement a constraint for an attribute in table A which depends on the value of an attribute in table B.
I was thinking this would work:
CREATE TABLE B (
ID INTEGER PRIMARY KEY,
Quantity INTEGER,
...,
);
CREATE TABLE A (
ID INTEGER PRIMARY KEY,
OtherID INTEGER,
Quantity INTEGER CHECK(Quantity > 0
AND Quantity <=
SELECT B.Quantity FROM B WHERE ID == B.ID)
);
When I run this I get an error around the SELECT statement. How can I enforce a constraint so that no row is added to table A where A.Quantity > B.Quantity?

Show the names of customers that have accounts SQL Query Oracle 10G

create table customer
(cust_id integer not null,
cust_name char(20) not null ,
cust_address varchar2(200) ,
emp_id integer not null,
constraint pk_customer primary key(cust_id)
);
create table account
(account_number integer not null,
account_balance number(8,2) not null,
constraint pk_acount primary key(account_number)
);
create table has
(cust_id integer not null,
account_number integer not null,
constraint pk_has
primary key(cust_id, account_number) )
alter table has
add constraint fk_account_has foreign key(account_number)
references account(account_number);
alter table has
add constraint fk_customer_has foreign key(cust_id)
references customer(cust_id);
Q1 Show the names of customers that have accounts
Q2 Show the customer names with the names of the employees they deal with**
Q1 is a simple lookup of the cust_id in junction table has:
select c.cust_name
from customer c
where exists (select 1 from has h where h.cust_id = c.cust_id)
This phrases as: select the customers that have at least one entry in the has table.
When it comes to Q2: your data structures show no sign of employees (all we have is customers and accounts), so this cannot be answered based on the information that you provided. You might want to ask a new question for this, providing sample data for the involved tables, along with desired results and you current attempt at solving the problem.

PostgreSQL SELECT JOIN

I have a problem with making a proper SELECT for my exercise:
There are two tables that I have created:
1. Customer
2. Order
ad. 1
CREATE TABLE public."Customer"
(
id integer NOT NULL DEFAULT nextval('"Customer_id_seq"'::regclass),
name text NOT NULL,
surname text NOT NULL,
address text NOT NULL,
email text NOT NULL,
password text NOT NULL,
CONSTRAINT "Customer_pkey" PRIMARY KEY (id),
CONSTRAINT "Customer_email_key" UNIQUE (email)
)
ad.2
CREATE TABLE public."Order"
(
id integer NOT NULL DEFAULT nextval('"Order_id_seq"'::regclass),
customer_id integer NOT NULL,
item_list text,
order_date date,
execution_date date,
done boolean DEFAULT false,
confirm boolean DEFAULT false,
paid boolean DEFAULT false,
CONSTRAINT "Order_pkey" PRIMARY KEY (id),
CONSTRAINT "Order_customer_id_fkey" FOREIGN KEY (customer_id)
REFERENCES public."Customer" (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
Please do not mind how columns properties were set.
The problem I have is following:
How to make a SELECT query which will give me as a result ids and emails of customers who have ordered something after '2017-09-15'
I suppose that this should go with JOIN but none of the queries I tried have worked :/.
Thanks!
You should post the queries that you tried, but in the meantime try this. It's a simple join :
SELECT DISTINCT id
, email
FROM public."Customer" c
JOIN public."Order" o
ON c.id = o.customer_id
WHERE order_date > '2017-09-15'
In table "Order" you just need to add current constraint for customer id:
customer_id integer REFERENCES Customer (id)
for more information check this page:
https://www.postgresql.org/docs/9.2/static/ddl-constraints.html
So, the query should be like this:
SELECT id, email
FROM Customer
INNER JOIN Order
ON (Order.customer_id = Customer.id)
WHERE order_date >= '2017-09-15'
Also, the useful docs you can check: https://www.postgresql.org/docs/current/static/tutorial-join.html

How do I find out the Top N diseases according to the cost of their treatment?

This is what I've tried so far
SELECT DISTINCT
RECORDS.TOTAL_COST, DISEASE.DISEASE_ID
FROM
RECORDS, DISEASE
WHERE
DISEASE.DISEASE_ID = RECORDS.DISEASE_ID
AND TREATMENT.TREATMENT_ID = RECORDS.TREATMENT_ID
GROUP BY
DISEASE.DISEASE_NAME
This is the star schema for the data provided
Treatment table
CREATE TABLE treatment
(
treatment_id NUMBER(6),
treatment_type VARCHAR2(30),
private_cost NUMBER(8,2),
public_cost NUMBER(8,2),
description VARCHAR
)
Create the records fact table
CREATE TABLE records
(
patient_id NUMBER(6),
doctor_id NUMBER(6),
disease_id NUMBER(6),
treatment_id NUMBER(6),
time_id DATE,
side_effects NUMBER(1),
effectivness NUMBER(1),
total_cost NUMBER(8,2)
);
Create foreign keys to all dimensional tables
ALTER TABLE records
ADD ( CONSTRAINT records_patients_fk FOREIGN KEY (patient_id) REFERENCES patients,
CONSTRAINT records_doctors_fk FOREIGN KEY (doctor_id) REFERENCES doctors,
CONSTRAINT records_disease_fk FOREIGN KEY (disease_id) REFERENCES disease,
CONSTRAINT records_treatment_fk FOREIGN KEY (treatment_id) REFERENCES treatment,
CONSTRAINT records_times_fk FOREIGN KEY (time_id) REFERENCES times);
CREATE TABLE disease
(
disease_id NUMBER(6),
disease_name VARCHAR2(30)
);
Assuming the data returned in the first query is mostly correct aside from wanting only the top N items:
SELECT TOTAL_COST, DISEASE_ID
FROM
(
SELECT DISTINCT RECORDS.TOTAL_COST, DISEASE.DISEASE_ID
FROM RECORDS, DISEASE
WHERE DISEASE.DISEASE_ID=RECORDS.DISEASE_ID AND
TREATMENT.TREATMENT_ID=RECORDS.TREATMENT_ID
GROUP BY DISEASE.DISEASE_NAME
ORDER BY RECORDS.TOTAL_COST DESC
)
WHERE ROWNUM <= 5; -- replace 5 with however many you want.