Get a descending list of items using two tables - sql

CREATE TABLE [dbo].[HistoricoSeries] (
[IDHistoricoSeries] INT IDENTITY (1, 1) NOT NULL,
[IDUtilizador] INT NOT NULL,
[codepisodio] INT NOT NULL,
CONSTRAINT [PK_historicoseries] PRIMARY KEY CLUSTERED ([IDHistoricoSeries] ASC),
CONSTRAINT [FK_96] FOREIGN KEY ([IDUtilizador]) REFERENCES [dbo].[Utilizadores] ([IDUtilizador]),
CONSTRAINT [FK_hse] FOREIGN KEY ([codepisodio]) REFERENCES [dbo].[EPISODIOS] ([codepisodio])
);
CREATE TABLE [dbo].[EPISODIOS] (
[idepisodio] INT IDENTITY (1, 1) NOT NULL,
[codepisodio] INT NOT NULL,
[codserie] INT NOT NULL,
[codtemporada] INT NOT NULL,
[numeroepisodio] INT NOT NULL,
[tituloepisodio] VARCHAR (53) NOT NULL,
[duracaominutos] INT NOT NULL,
PRIMARY KEY CLUSTERED ([codepisodio] ASC)
);
These are my table definitions.
string maisVistoEpisodio = "SELECT * FROM EPISODIOS WHERE EPISODIOS.codepisodio IN (SELECT codepisodio, count(codepisodio) AS mais_vistos FROM HISTORICOSERIES GROUP BY codepisodio ORDER BY COUNT (codepisodio) DESC)";
This is my SQL Server query that i've been from quite sometime hacking away with no results.
My end goal was to have a listing of the most watched episodes from the table EPISODIOS, but the error
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
arose itself and I don't know how to fix.
Can anyone shed a bit of light?
Thanks.

Your code looks like SQL Server. If so, you can use TOP WITH TIES in the subquery:
SELECT E.*
FROM EPISODIOS E
WHERE E.codepisodio IN (SELECT TOP (1) WITH TIES HS.codepisodio
FROM HISTORICOSERIES HS
GROUP BY HS.codepisodio
ORDER BY COUNT(*) DESC
)

Related

How do i select the highest number in one column and then search the the id in other table

How do I select the highest number in one column and then search the the ID in other table?
I have these two tables:
create table armazens_has_artigos
(
stockMinimo int not null,
stockQuantidade int not null,
idArtigos int not null,
idArmazens int not null,
idZonasFisicas int not null
constraint fk_armazens_has_artigos_idArtigos
foreign key (idArtigos)
references artigos (idArtigos) on delete cascade,
constraint fk_armazens_has_artigos_idArmazens
foreign key (idArmazens)
references armazens (idArmazens) on delete cascade,
constraint fk_armazens_has_artigos_zonasFisicas_idZonasFisicas
foreign key (idZonasFisicas)
references zonasFisicas (idZonasFisicas) on delete cascade
);
In this one I need to select the highest StockQuantidade and then with the same id select in this table the nome
create table artigos
(
idArtigos int primary key,
nome varchar (45) not null,
descr varchar (45) not null,
precoCompra float not null,
precoVenda float not null,
unidadeRepresentacao varchar (45) not null
);
There might be more then one Artigos matching the criteria:
SELECT *
FROM artigos
WHERE idArtigos IN
(
SELECT idArtigos
FROM dbo.armazens_has_artigos
WHERE stockQuantidade =
(
SELECT MAX(stockQuantidade)FROM armazens_has_artigos
)
);
SELECT
nome
FROM artigos
JOIN armazens_has_artigos
ON armazens_has_artigos.idArtigos = artigos.idArtigos
WHERE armazens_has_artigos.stockQuantidade = (SELECT
MAX(stockQuantidade)
FROM armazens_has_artigos)

Total sum of price and quantity in oracle

I have a problem. I need to calculate a total sum of order in my DB. I have 3 tables:
CREATE TABLE Potrawa(
id_potrawy INT CONSTRAINT Potrawa_PK PRIMARY KEY,
Nazwa VARCHAR2(150) NOT NULL,
Cena NUMBER(6,2) NOT NULL, **(PRICE)**
Opis VARCHAR(100)
);
CREATE TABLE Zamowienie(
id_zamowienia INT CONSTRAINT Zamowienie_PK PRIMARY KEY,
Ilosc INT, **(QUANTITY)**
Data DATE,
Ocena INT CONSTRAINT Ocena_Zamowienie_CHECK CHECK (Ocena IN (1, 2, 3, 4, 5)),
klient_id INT CONSTRAINT Zamowienie_Klient_FK REFERENCES Klient(id_klient),
pracownik_id INT CONSTRAINT Zamowienie_Pracownik_FK REFERENCES Pracownik(id_pracownik),
potrawy_id INT CONSTRAINT Zamowienie_Menu_FK REFERENCES Potrawa(id_potrawy),
typ_zamowienia_id INT CONSTRAINT Zamowienie_Typ_FK REFERENCES Typ_zamowienia(id_typ_zamowienia)
);
CREATE TABLE Menu(
restauracja_id INT NOT NULL CONSTRAINT Menu_Restauracje_FK REFERENCES Restauracja(id_restauracja),
potrawa_id INT NOT NULL CONSTRAINT Menu_Potrawa_FK REFERENCES Potrawa(id_potrawy),
CONSTRAINT Menu_PK PRIMARY KEY(restauracja_id, potrawa_id),
rodzaj_menu_id INT CONSTRAINT Menu_Rodzaj_Menu_FK REFERENCES Rodzaj_menu(id_rodzaj_menu)
);
I want to write a query that show me sum of each order. I wrote sth like this, but it's not working. Sum is not that I expect.
select distinct z.id_zamowienia as "zamowienie", z.potrawy_id as "Potrawa", p.nazwa as "Nazwa potrawy", z.ilosc as ILOSC,
count(*) over(partition by z.potrawy_id, z.id_zamowienia) * p.cena AS "CENA"
from potrawa p, menu m, zamowienie z
where p.id_potrawy = m.potrawa_id and m.potrawa_id = z.potrawy_id
Can someone give me tip how to fix it or how can I do it in another way (PARTITION BY is obligatory).
First of all it's always better to use proper join syntax. Do you want to find sum(Ilosc) instead of count(*) for that partition?
select distinct
z.id_zamowienia as "zamowienie",
z.potrawy_id as "Potrawa",
p.nazwa as "Nazwa potrawy",
z.ilosc as ILOSC,
sum(Ilosc) over(partition by z.potrawy_id, z.id_zamowienia) * p.cena AS "CENA"
from
potrawa p
inner join menu m on p.id_potrawy = m.potrawa_id
inner join zamowienie z and m.potrawa_id = z.potrawy_id

How to get the highest appearance value in one table, from another table?

So I have 3 tables referencing cars, assurance and accident.
I want to know the brand of vehicles who had the most accidents, compared to others.
I have tried a lot of ways to that, but mostly i only get or all the brands returned or the brand of the car that was registered the most, not the one that had most accidents
These are my tables
create table car(
n_veic bigint not null,
matric varchar(15) not null,
pais_matric text not null,
n_pess bigint not null,
tipo text not null,
cor text not null,
brand text not null,
modelo varchar(15),
primary key(n_veic),
unique(matric),
foreign key (n_pess) references pessoa(n_pess)
);
create table ensurance(
apolice bigint not null,
segurado bigint not null,
car bigint not null,
datai date not null,
dataf date not null,
cobertura numeric(10,2) not null,
primary key(apolice),
unique(segurado, veiculo),
foreign key (segurado) references pessoa(n_pess),
foreign key (car) references car(n_veic)
);
create table accident(
n_acid bigint not null,
pess_segura bigint not null,
veic_seguro bigint not null,
data date not null,
local varchar(255) not null,
descr text not null,
primary key(n_acid),
unique(n_acid, veic_seguro),
foreign key (pess_segura,veic_seguro) references ensurance(segurado, car)
This is what i tried
SELECT marca
FROM veiculo NATURAL JOIN acidente
GROUP BY marca
HAVING count (distinct n_veic)>=ALL
(SELECT count (distinct n_veic)
FROM veiculo NATURAL JOIN acidente
GROUP BY marca);
I think the logic is:
select c.marca, count(*) as num_acidentes
from acidente a join
car c
on a.veic_seguro = c.n_veic
group by c.marca
order by num_acidentes desc;
You can use fetch first 1 row only -- or whatever is appropriate for your database -- to get only one row.
Try this-
Note:
1. Try to avoid NATURAL JOIN and use specific column reference.
2. Rethink DISTINCT for count is really necessary or not.
SELECT TOP 1 marca, COUNT(DISTINCT n_veic)
FROM veiculo
NATURAL JOIN acidente
GROUP BY marca
ORDER BY COUNT(DISTINCT n_veic) DESC

SQL Logic and Aggregate Issue

I have the following problem to solve in SQL :
d) A query that provides management information on take up of the various types of activities on offer. For each type of activity, the query should show the total number of individuals who took that type of activity and the average number of individuals taking each type of activity.
Here are my tables :
CREATE TABLE accommodations
(
chalet_number int PRIMARY KEY,
chalet_name varchar(40) NOT NULL,
no_it_sleeps number(2) NOT NULL,
indivppw number(4) NOT NULL
)
CREATE TABLE supervisors
(
supervisor_number int PRIMARY KEY,
supervisor_forename varchar(30) NOT NULL,
supervisor_surname varchar(30) NOT NULL,
mobile_number varchar(11) NOT NULL
)
CREATE TABLE visitors
(
visitor_ID int PRIMARY KEY,
group_ID int NOT NULL,
forename varchar(20) NOT NULL,
surname varchar(20) NOT NULL,
dob date NOT NULL,
gender varchar(1) NOT NULL
)
CREATE TABLE activities
(
activity_code varchar(10) PRIMARY KEY,
activity_title varchar(20) NOT NULL,
"type" varchar(20) NOT NULL
)
CREATE TABLE "groups"
(
group_ID int PRIMARY KEY,
group_leader varchar(20) NOT NULL,
group_name varchar(30)
number_in_group number(2) NOT NULL
)
CREATE TABLE bookings
(
group_ID int NOT NULL,
start_date date NOT NULL,
chalet_number int NOT NULL,
no_in_chalet number(2) NOT NULL,
start_date date NOT NULL,
end_date date NOT NULL,
CONSTRAINT bookings_pk PRIMARY KEY(group_ID, chalet_number));
CREATE TABLE schedule
(
schedule_ID int PRIMARY KEY,
activity_code varchar(10) NOT NULL,
time_of_activity number(4,2) NOT NULL,
am_pm varchar(2) NOT NULL,
"date" date NOT NULL
)
CREATE TABLE activity_bookings
(
visitor_ID int NOT NULL,
schedule_ID int NOT NULL,
supervisor_number int NOT NULL,
comments varchar(200),
CONSTRAINT event_booking_pk PRIMARY KEY(visitor_ID, schedule_ID));
ALTER TABLE visitors
ADD FOREIGN KEY (group_ID)
REFERENCES "groups"(group_ID)
ALTER TABLE Schedule
ADD FOREIGN KEY (activity_code)
REFERENCES activities(activity_code)
ALTER TABLE bookings
ADD FOREIGN KEY (group_ID)
REFERENCES "groups"(group_ID)
ALTER TABLE bookings
ADD FOREIGN KEY (chalet_number)
REFERENCES accommodations(chalet_number)
ALTER TABLE activity_bookings
ADD FOREIGN KEY (visitor_ID)
REFERENCES visitors(visitor_ID)
ALTER TABLE activity_bookings
ADD FOREIGN KEY (schedule_ID)
REFERENCES schedule(schedule_ID)
ALTER TABLE activity_bookings
ADD FOREIGN KEY (supervisor_number)
REFERENCES supervisors(supervisor_number)
I have the following solution:
SELECT activities."type", 'overalltotal' AS OT, ('overalltotal' / 'activities') AS AVG
FROM activities, schedule
WHERE 'overalltotal' = (SELECT SUM(COUNT(schedule_ID))
FROM activities, schedule
WHERE schedule.activity_code = activities.activity_code
GROUP BY activities."type"
)
AND 'activities' = (SELECT COUNT(DISTINCT activities."type")
FROM activities
)
AND schedule.activity_code = activities.activity_code
GROUP BY activities."type";
I have implemented sample data and code to check the variables above:
SELECT SUM(COUNT(schedule_ID))
FROM activities, schedule
WHERE schedule.activity_code = activities.activity_code
GROUP BY activities."type";
Result : 20
SELECT COUNT(DISTINCT activities."type")
FROM activities;
Result : 5
However when running the code :
ORA-01722: invalid number
01722. 00000 - "invalid number"
*Cause:
*Action:
EDIT:
Using Dave's Code i have the following output:
Snowboarding 15
sledding 19
Snowmobiling 6
Ice Skating 5
Skiing 24
How would i do the final part of the question?
and the average number of individuals taking each type of activity.
You must use double quotes around column names in Oracle, not single quotes. For example, "overalltotal". Single quotes are for text strings, which is why you're getting an invalid number error.
EDIT: This is probably the type of query you want to use:
SELECT activities."type", COUNT(*) AS total, COUNT(*)/(COUNT(*) OVER ()) AS "avg"
FROM activities a
JOIN schedule s ON a.activity_code=s.activity_code
JOIN activity_bookings ab ON s.schedule_ID=ab.schedule_ID
GROUP BY activities."type";
Basically, because each activity booking has one visitor id, we want to get all the activity bookings for each activity. We have to go through schedule to do that. They we group the rows by the activity type and count how many activity bookings we have for each type.

SQL Server composite key problem

I have 2 tables:
create table numbers2
(
id1 int IDENTITY(1,1) not null,
id2 int not null,
primary key(id1, id2)
)
and table 2
create table ttt
(
id int identity(1,1) not null,
first_name varchar(50) null,
last_name varchar(50) null,
sex varchar(1) check (sex in ('m', 'f')) null,
number_id int not null,
id_id1 int not null,
id_id2 int not null,
primary key(id),
constraint fk_numbers_id1 foreign key (id_id1) references numbers2(id1)
on update no action
on delete no action
)
The problem is how to add constraint "fk_numbers_id1" so it will only reference one part of the composite key from table numbers2. Is it possible or there is other solution?
Create a unique constraint on numbers2.id1:
create table numbers2
(
id1 int IDENTITY(1,1) not null,
id2 int not null,
primary key(id1, id2),
unique(id1)
)
I would like to know why you chose to create the primary key over two columns, where the first column is already unique by itself. I'm sure this violates some kind of Normal Form rule but I can't remember which one.
If you did it in order to cover the data in both columns, then it is unnecessary to do that, just do this instead (assuming that the data in id1 is genuinely unique):
create table numbers2
(
id1 int IDENTITY(1,1) not null,
id2 int not null,
primary key(id1),
)
create index cover_id2 on numbers2(id2) -- no need to include clustered index columns in a covering index