Column not recognized in select statement - sql

Im getting an error in the Select statement of this code.
SELECT Track.Name, Track.UnitPrice,
Count(*) AS Purchase_count,
Purchase_count * Track.UnitPrice AS Total_per_track
FROM Track
JOIN InvoiceLine ON Track.TrackId = InvoiceLine.TrackId
GROUP BY Track.Name
ORDER BY Total_per_track desc
LIMIT 10;
The Error returning is
Result: no such column: Purchase_count
At line 1:
SELECT Track.Name, Track.UnitPrice,
Count(*) AS Purchase_count,
Purchase_count * Track.UnitPrice AS Total_per_track
FROM Track
JOIN InvoiceLine
ON Track.TrackId = InvoiceLine.TrackId
GROUP BY Track.Name
ORDER BY Total_per_track desc
LIMIT 10;

You can't refer to an alias defined in the SELECT clause in the same clause (nor in the WHERE clause for example). You need to either repeat the original expression, or use a derived table (subquery or cte).
Here the expression is simple enough so repeating seems more relevant:
SELECT
t.Name,
t.UnitPrice,
COUNT(*) AS Purchase_count,
COUNT(*) * t.UnitPrice AS Total_per_track
FROM Track t
INNER JOIN InvoiceLine il ON t.TrackId = il.TrackId
GROUP BY t.TrackId, t.Name, t.UnitPrice
ORDER BY Total_per_track desc
LIMIT 10;
Notes:
I added TrackId and UnitPrice to the GROUP BY clause; TrackId is there to avoid wrongly grouping together two tracks that would have the same Name; UnitPrice appears in the SELECT clause and is not part of an aggregate function, so it is a good practice to have it in the GROUP BY clause too (although, it does seem to be functionally dependant on TrackId)
table aliases make the query shorter to read and write

In order to order by Total_per_track you need to use a table expression.
For example:
select *
from (
SELECT
Track.Name, Track.UnitPrice,
Count(*) AS Purchase_count,
Count(*) * Track.UnitPrice AS Total_per_track
FROM Track
JOIN InvoiceLine
ON Track.TrackId = InvoiceLine.TrackId
GROUP BY Track.Name
) x
ORDER BY Total_per_track desc
LIMIT 10

Related

Trouble Aliasing tables when using subqueries and INNER JOIN

H​ello! I have two tables: trips and stations, and I'm trying to print the ID and name from a distinct station along with the total number of rides from that station.
The ID and name come from the stations table, while the number of trips comes from the trips table, so I'd went ahead and created a query to:
SELECT id, name and num_rides
FROM (SELECT COUNT (*) num_rides FROM tableB AS b) AS num_rides
INNER JOIN tableA AS a ON a.station_id = b.start_station_id
The problem is in the JOIN statement of the outer query, where it doesn't seem to recognize the "b" alias for my table, which I aliased in the inner query.
I tried running the queries separately, and they both work fine. I'm assuming then, that the problem is that the computer doesn't remember my inner query alias on the outer query, but that doesn't make much sense, does it?
Error states: "Unrecognized name: trips" ---> trips being the alias I used for table B.
SELECT
station_id,
name,
num_of_rides AS num_of_rides_starting_at
FROM
(
SELECT
start_station_id,
COUNT(*) number_of_rides
FROM
bigquery-public-data.new_york_citibike.citibike_trips AS trips
GROUP BY
trips.start_station_id
)
AS num_of_rides
INNER JOIN
bigquery-public-data.new_york_citibike.citibike_stations AS stations ON stations.station_id = trips.start_station_id
ORDER BY num_of_rides DESC ```
I believe the issue is that the "trips" alias is only active inside the parentheses. Try naming that whole select statement and referencing that name.
SELECT
station_id,
name,
num_of_rides AS num_of_rides_starting_at
FROM
(
SELECT
start_station_id,
COUNT(*) number_of_rides
FROM
bigquery-public-data.new_york_citibike.citibike_trips AS trips
GROUP BY
trips.start_station_id
) NeedNameHere
AS num_of_rides
INNER JOIN
bigquery-public-data.new_york_citibike.citibike_stations AS stations
ON stations.station_id = NeedNameHere.start_station_id
ORDER BY num_of_rides DESC
Hope this may help
SELECT
station_id, /*from table: citibike_stations */
name, /*from table: citibike_trips */
number_of_rides AS number_of_rides_starting_at_station /*from table: station_num_trips*/
FROM
(SELECT
start_station_id,
COUNT(*) number_of_rides
FROM `bigquery-public-data.new_york_citibike.citibike_trips`
GROUP BY
start_station_id
)
AS station_num_trips
INNER JOIN
`bigquery-public-data.new_york_citibike.citibike_stations`
ON
station_id = start_station_id
ORDER BY
number_of_rides DESC

Selecting rows with the most repeated values at specific column

Problem in general words: I need to select value from one table referenced to the most repeated values in another table.
Tables have this structure:
screenshot
screenshot2
The question is to find country which has the most results from sportsmen related to it.
First, INNER JOIN tables to have relation between result and country
SELECT competition_id, country FROM result
INNER JOIN sportsman USING (sportsman_id);
Then, I count how much time each country appear
SELECT country, COUNT(country) AS highest_participation
FROM (SELECT competition_id, country FROM result
INNER JOIN sportsman USING (sportsman_id))
GROUP BY country
;
And got this screenshot3
Now it feels like I'm one step away from solution ))
I guess it's possible with one more SELECT FROM (SELECT ...) and MAX() but I can't wrap it up?
ps:
I did it with doubling the query like this but I feel like it's so inefficient if there are millions of rows.
SELECT country
FROM (SELECT country, COUNT(country) AS highest_participation
FROM (SELECT competition_id, country FROM result
INNER JOIN sportsman USING (sportsman_id)
) GROUP BY country
)
WHERE highest_participation = (SELECT MAX(highest_participation)
FROM (SELECT country, COUNT(country) AS highest_participation
FROM (SELECT competition_id, country FROM result
INNER JOIN sportsman USING (sportsman_id)
) GROUP BY country
))
Also I did it with a view
CREATE VIEW temp AS
SELECT country as country_with_most_participations, COUNT(country) as country_participate_in_#_comp
FROM(
SELECT country, competition_id FROM result
INNER JOIN sportsman USING(sportsman_id)
)
GROUP BY country;
SELECT country_with_most_participations FROM temp
WHERE country_participate_in_#_comp = (SELECT MAX(country_participate_in_#_comp) FROM temp);
But not sure if it's easiest way.
If I understand this correctly you want to rank the countries per competition count and show the highest ranking country (or countries) with their count. I suggest you use RANK for the ranking.
select country, competition_count
from
(
select
s.country,
count(*) as competition_count,
rank() over (order by count(*) desc) as rn
from sportsman s
inner join result r using (sportsman_id)
group by s.country
) ranked_by_count
where rn = 1
order by country;
If the order of the result rows doesn't matter, you can shorten this to:
select s.country, count(*) as competition_count
from sportsman s
inner join result r using (sportsman_id)
group by s.country
order by count(*) desc
fetch first rows with ties;
You seem to be overcomplicating this. Starting from your existing join query, you can aggregate, order the results and keep the top row(s) only.
select s.country, count(*) cnt
from sportsman s
inner join result r using (sportsman_id)
group by s.country
order by cnt desc
fetch first 1 row with ties
Note that this allows top ties, if any.
SELECT country
FROM (SELECT country, COUNT(country) AS highest_participation
FROM (SELECT competition_id, country FROM result
INNER JOIN sportsman USING (sportsman_id)
) GROUP BY country
order by 2 desc
)
where rownum=1

Simple WHERE clause breaking sqlite query

I have a working query here:
SELECT tlt.name AS theme, COUNT(*) AS nsets
FROM tlt
INNER JOIN sets
ON tlt.id = sets.theme_id
GROUP BY tlt.name
ORDER BY nsets DESC;
But when I add a WHERE clause sqlite throws a syntax error "near" the WHERE clause
SELECT tlt.name AS theme, COUNT(*) AS nsets
FROM tlt
INNER JOIN sets
ON tlt.id = sets.theme_id
GROUP BY tlt.name
WHERE nsets > 50
ORDER BY nsets DESC;
I'm confused why this simple WHERE clause breaks this query.
A WHERE clause must be before GROUP BY, not after. But you cannot use an alias or an aggregate function in a WHERE clause, so you need to use HAVING COUNT(*) > 50 where you currently have your WHERE clause.
SELECT tlt.name AS theme, COUNT(*) AS nsets
FROM tlt
INNER JOIN sets
ON tlt.id = sets.theme_id
GROUP BY tlt.name
HAVING COUNT(*) > 50
ORDER BY nsets DESC;

Limiting SQL Result

I have a query where I am trying to get results from a table:
SELECT P.P_CODE, P.P_JEWELRYTYPE,P.p_catalog, P_AVAILABLE, P_RESERVED , p.p_catalog
FROM products P
WHERE
P.p_catalog IN (8796093383256,8796093252184,8796093317720,8796093121112,8796093186648);
I want a query where I can limit the number of results to 500 of each catalog type. How should I modify my query to achieve this?
Analytical function row_number() will work which will assign row numbers to each p_catalog so that you could filter on that condition in WHERE clause in an outer query:
SELECT *
FROM (
SELECT
p.P_CODE, p.P_JEWELRYTYPE, p.p_catalog, p.P_AVAILABLE, p.P_RESERVED, p.p_catalog,
row_number() over (partition by p.p_catalog) as rn
FROM products p
WHERE p.p_catalog IN (8796093383256,8796093252184,8796093317720,8796093121112,8796093186648)
) p
WHERE rn <= 500;
Use row_number():
select p.*
from (select p.*, row_number() over (partition by catalog order by null) as seqnum
from products p
) p
where p.seqnum <= 500;
You can put the where filtering in either the inner or outer query.

How do I join this sql query to another table?

I have the following SQL query and so far it works the way it should and gets the top 40 tag ids that I have stored in the tagmap table.
SELECT TOP 40
tbrm_TagMap.TagID,
Count(*)
FROM tbrm_TagMap
GROUP BY tbrm_TagMap.TagID
ORDER BY COUNT(tbrm_TagMap.TagID) DESC
I also want to join to the Tags table which contains the actual name of each TagID. Each attempt I make comes back with an error. How can I achieve this? I am using SQL 2008.
SELECT *
FROM (
SELECT TOP 40
tbrm_TagMap.TagID, COUNT(*) AS cnt
FROM tbrm_TagMap
GROUP BY
tbrm_TagMap.TagID
ORDER BY
COUNT(*) DESC
) q
JOIN Tags
ON Tags.id = q.TagID
ORDER BY
cnt DESC
My guess is that when you were joining tags, you weren't including it in the group by clause, which will always through an error in SQL Server. Every column not aggregated but returned needs to be in the group by.
Try something like this:
SELECT TOP 40
tbrm_TagMap.TagID,
t.Tag,
Count(*)
FROM
tbrm_TagMap
INNER JOIN tags t ON
tbrm_TagMap.TagID = t.TagID
GROUP BY
tbrm_TagMap.TagID,
t.Tag
ORDER BY 3 DESC
SELECT TOP 40
tbrm_TagMap.TagID, Tags.TagName Count(*)
FROM tbrm_TagMap INNER JOIN Tags ON tbrm_TagMap.TagID = Tags.TagID
GROUP BY tbrm_TagMap.TagID, Tags.TagName
ORDER BY COUNT(tbrm_TagMap.TagID) DESC
Try this..
SELECT top 40 tags.TagDescription, tbrm_TagMap.TagID, Count(*)
FROM tbrm_TagMap
INNER JOIN Tags
ON TagMap.TagID = Tags.TagId
GROUP BY tags.TagDescription, tbrm_TagMap.TagID
ORDER BY COUNT(tbrm_TagMap.TagID) DESC