Apologies if the title doesn't make full sense, I'll try to explain as best I can.
I have a table containing information about vehicles, there are many duplicates and around 5000 rows overall. Here's a snippet as an example:
As you can see the model '159 TI TBI' repeats twice, this essentially means there are two of these cars stored in London.
I am looking for something like below, where there is a count of how many times a particular vehicle in a particular location repeats, as well as removing duplicates so each vehicle only appears once for each location.
I am able to do a fairly simple select command for a particular vehicle and location, such as
SELECT COUNT(model), model, loc_name, vehicle_type
FROM vehicles
WHERE loc_name='London' AND model='159 TI TBI'
GROUP BY model, loc_name, vehicle_type
The issue is that I'd be repeating this command for every combination of a vehicle model in a particular location, it's not very efficient.
Hopefully this makes some sense, I haven't had a huge amount of experience with SQL so apologies if anything is badly wrong. Thanks.
This query will give you the required results
SELECT COUNT(model) cnt, model, loc_name, vehicle_type
FROM vehicles
GROUP BY model, loc_name, vehicle_type
Your question is a bit unclear. But let me try. It seems you think to get the count for each group, you would have to re-query with for each vehicle in the where clause. However, aggregation will allow you to get the count across all the vehicles. If you are just looking for the model, location, type uniquely and the count of occurrences, you have the right query, just remove your where clause and the power of SQL will take care of it for you.
SELECT COUNT(*) as quantity, model, loc_name, vehicle_type
FROM vehicles
GROUP BY model, loc_name, vehicle_type
if you want only the rows with more then one occurrence you can use having for filter th aggregated result
SELECT COUNT(*) as quantity, model, loc_name, vehicle_type
FROM vehicles
GROUP BY model, loc_name, vehicle_type
having count(*) > 1
Related
I'm trying to use a common table expression to find the differences between two queries I wrote. The first query returns how many patients belong to each ROOMID(each ID represent a specific room).
Second query I have is how many patients that belong to each ROOMId have surgery operated on them. PatientID represent each patient.
select roomID, count(distinct patientID) as totalinsurgery
from data with (nolock)
where ptprocess = 'surgery'
group by clientid, batchid
Second query:
select CAroomid, sum(patientsinroom) as patientsinroom
from data
group by caroomid
So the idea behind is try to get the 'difference' in result of the two query. So how many patients in the room went to surgery. What is the best way to use common table expression to get the result?
So how many patients in the room went to surgery.
I suspect you just want conditional aggregation:
select roomId,
count(distinct case when ptprocess = 'surgery' then patientID end) as num_surgery
count(distinct patientID) as total
from data
group by roomId;
Note: I have no idea why you are using count(distinct). Can a patient really occur more than one time in a room?
This is my cars table which has 1000 rows. Each of make or manufacturer has different model and same model can have different price.
I have to output min price among all of the model of each manufacturer and i cant think of any way to do this.
Nearest to what i got is,
SELECT make, model, min(price) FROM car
GROUP BY model, make
ORDER BY make;
which outputs,527 rows
But i want min price among all of the models of each make.
HELP!!
In Postgres, I recommend distinct on for this purpose:
select distinct on (make) c.*
from cars c
order by make, price asc;
From your question it seems that you want minimum price of each make.
The following query can help in my opinion.
SELECT make,MIN(price) from car
group by make
order by make;
Assuming you need "the lowest priced Model for each Make", you can easily get the lowest price per Make according to the answers given, but that will not give you the Model name!
I'd suggest using a window function to rank the data, partitioning by Make, and ordering by Price ascending. Then simply select all rows ranked 1.
There may be a possibility that two Models within a Make may be equally low priced. In that case, you'd have two rows returned for that Make. If that's a possibility and also a problem, you'd have to engage in further processing to decide how to break the tie or consolidate the row into one (for example, by concatenating the Model names).
Use rank() window function inside a CTE to filter the minimum prices:
with cte as (
select *,
rank() over (partition by model order by price) rn
from car
)
select id, make, model, price
from cte
where rn = 1
order by make;
This will return ties in minimum price.
If you don't need ties replace rank() with row_number().
I assumed that a model name cannot be used by 2 makers. If this is not the case then change to this:
rank() over (partition by make, model order by price) rn
I think you are looking for a simple left join.
select t1.make, t1.model, t2.min_price
from car t1 left join (select make, min(price) min_price from car group by make) t2 on
t1.make=t2.make
I dont rly know how to explain my Problem, but i have a Query where i need to group by a column but on the other i need to get an avg of a column which is not grouped by.
My Code is like this:
Select SID,PID,Cost, AVG(COST)
from catalog
group by SID,PID
ORDER by SID
All Columns are in the same table.
What can i do to get the AVG(Cost) of PID?
My Question is related to an exam question which is the following: Find the SID's who charge more for some PID than the average cost of that PID.
The table has the columns SID, PID, COST. I cant upload pictures of the table because my account is new, so im sorry.
So my Problem was that i couldnt get the AVG of the PID, my next Problem because i already tried it with Partition is, that i dont know how the having clause has to look like. Do i need a sub-query for that?
You can use window functions to add an average to a row:
select SID, PID, Cost,
avg(cost) over (partition by pid) as avg_cost_for_pid
from catalog
order by sid;
Lets say we have a view/table hotel(hotel_n,hotel_name, room_n, price). I want to find the cheapest room. I tried group by room_n, but I want the hotels name (hotel_name) to be shown to the board without grouping it.
So as an amateur with sql(oracle 11g) I began with
select hotel_n, room_n, min(price)
from hotel
group by room_n;
but it shows the error: ORA-00979: not a GROUP BY expression. I know I have to type group by room_n, hotel_n, but I want the hotel_n to be seen in the table that I make without grouping by it!
Any ideas? thank you very much!
Aggregate functions are useful to show, well, aggregate information per group of rows. If you want to get a specific row from a group of rows in relation to the other group members (e.g., the cheapest room per room_n), you'd probably need an analytic function, such as rank:
SELECT hotel_n, hotel_name, room_n, price
FROM (SELECT hotel_n, hotel_name, room_n, price
RANK() OVER (PARTITION BY room_n ORDER BY price ASC) rk
FROM hotel) t
WHERE rk = 1
I am trying to get a Minimun price from a car in a table i have.. I am using DISTINCT
SELECT DISTINCT
datepart(year,[Registration]) AS YearRegistered,
MIN(SalePrice), Model, Make
FROM [VehicleSales]
But its not working, for example
without distinct returns many car makes and models so i use distinct so i get unique cars that are the same make and model and year....
I wish to incorporate a "Startign from price ..." hence the SalePrice can also be different for same model and make ... so i want to do a MIN..
But i am bit confused, the above is working working...
Any ideas?
You need to add a GROUP BY clause and get rid of the DISTINCT:
SELECT
datepart(year,[Registration]) AS YearRegistered,
MIN(SalePrice), Model, Make
FROM
[VehicleSales]
GROUP BY
datepart(year,[Registration]), Model, Make
SELECT DATEPART(year,[Registration]) AS YearRegistered, Model, Make, MIN(SalePrice)
FROM [VehicleSales]
GROUP BY
DATEPART(year,[Registration]) AS YearRegistered, Model, Make