How to add alias column in SQL Table? - sql

I need some assistance.
I have pursed the City name from the purchase address with the alias "City" .
Now I have a I have a problem statement saying "Find the top cities with the highest sales".
Now, the city column is not into the main table so I cannot run a group by operation. How would I perform this task?

If you're looking for a way to get the city with the highest number of Quantity_Ordered, you can try this.
Since your data table doesn't contain the city exactly but it needs to be parsed, it would probably be best to create a view.
CREATE VIEW vProductDataCity AS
SELECT *, PARSENAME... -- Fill the "..." with your parsing code
And then to get the top city:
SELECT TOP(1) city, SUM(Quantity_Ordered) as SumQuantity_Ordered
FROM vProductDataCity
GROUP BY city
ORDER BY SumQuantity_Ordered DESC;

Related

Why is my "where" statement not working when it's being designated?

I'm currently trying to write an SQL statement which does the following;
"The sales department now uses the abbreviation SL instead of SA. Change the abbreviation in the job description. Select all employees of the sales department except Taylor. Sort by the total."
This is the code i'm currently trying to run, any advice?
SELECT CONCAT("first_name","", "last_name")
FROM employees NOT "Taylor"
WHERE = "sl"
ORDER by verschil DESC
You have not stated which DMBS you are using. But you have a few obvious syntax errors.
You need to specify the column name for the department in the WHERE clause such as
SELECT ... FROM ... WHERE column_name = "sl" ORDER BY...;
I would suggest you also include your logic for excluding the person called "Taylor" inside the WHERE clause.
First of all, I am assuming you're working with postgresql, secondly you're trying to get all employees name from employees table who are from sales department (you need to replace column_name1 with the actual name of the column where 'SL' value is inserted, replace column_name2 by the name of the column by which you want the result to sort on).
select first_name, last_name
from employees
where first_name<>'Taylor' and last_name<>'Taylor' and column_name1='SL'
order by column_name2
This should fix your issue :
SELECT first_name," ",last_name
FROM employees
WHERE = "sl" and NOT "Taylor"
ORDER by verschil DESC

When is aliasing required when using SQL set theory clauses?

I just started learning SQL and am trying to learn from my mistakes. In one of my practice exercises, I had to find city names from the cities database are not listed as capital cities in countries database. Initially I tried the code below but it yielded an error.
SELECT name
FROM cities
EXCEPT
SELECT capital
FROM countries
ORDER BY capital ASC;
The correct code is:
SELECT city.name
FROM cities AS city
EXCEPT
SELECT country.capital
FROM countries AS country
ORDER BY name;
Can someone explain to me why aliasing made all the difference here?
An ORDER BY for a UNION, EXCEPT or INTERSECT sorts the complete result. The column names of the overall query are defined by the first query. So this query:
SELECT name
FROM cities
EXCEPT
SELECT capital
FROM countries
returns a result with a single column named name.
Adding an order by is conceptually the same as:
select *
from (
SELECT name
FROM cities
EXCEPT
SELECT capital
FROM countries
) x
order by ....;
As the inner query only returns a single column name, that's the only column you can use in the order by.
The aliases that you used in your second query don't change the column name of the overall result which determines the column names available for the order by clause.

Count specific column in DB2

I have a table contact with three columns e.g. name, surname and age.
I would like to count the number of entries from the specific column surname.
How looks the select statement in DB2 to achieve this?
You can change the column name using as :
select count(surname) as surname_count
from contact c;
I assume you want to perform a
select count(surname)
from contact
group by surname
but you need to put some effort into the question and prove you have already researched a bit beforehand

How can I query to find max population of country from countries table?

I have a table "countries" with columns -> name,continent,area,popualtion.
Let's say I want to find the name and population of the chosen country with the highest population.
SELECT MAX(population) FROM countries;
The example above returns the maximum population.
I want it to also see the name of the country with that population.
SELECT name,MAX(population) FROM countries;
I am getting the error like below.
ERROR: column "countries.name" must appear in the GROUP BY clause or be used in an aggregate function
I can't think of another way to do it.
Here is an example of my query.
SELECT name,population
FROM countries
WHERE population >= (
SELECT MAX(population)
FROM countries)
;
This query works, but I am also curious why am I getting the error or if anyone knows if there is any better ways to accomplish this?
SELECT name, population
FROM countries
ORDER BY population DESC
LIMIT 1
MAX selects the maximum element from a list of values. In your first query,
SELECT MAX(population) FROM countries;
the list is formed by extracting the population field from all rows in countries, and then the maximum is selected. This collapses the list of rows down to a single row containing just the maximum.
In your second query,
SELECT name,MAX(population) FROM countries;
you (conceptually) get a list of all name fields from countries, but there's only one MAX(population). The database system doesn't know what to do with this: SELECT name FROM countries would return as many rows as there are in countries, but SELECT MAX(population) FROM countries would only return one row. This doesn't match up; it's unclear how many rows you want returned from this. This is why you get an error.
The error message says you need to either
use name in an aggregate function, which would collapse the list of rows down to a single value, which could be returned along the single MAX value, or
use a GROUP BY name clause, which would group the list of countries into entries with equal names first, then compute MAX(population) separately for each group. This makes no sense if all your countries have different names.
As far as I know there's no SQL syntax for "select the maximum population and then get the name field from the same row" (it's not quite clear what this would do anyway because there can be more than one country with a population equal to the maximum).
What you can do instead is sort the whole table, then select only fields from the first row:
SELECT name, population
FROM countries
ORDER BY population DESC
LIMIT 1
(I'm pretty sure Postgres optimizes this so there's no actual sort involved.)
Now if there is more than one country with a maximum population, you'll get a random result (we haven't told the database how to sort rows with equal population).
You can make use of Top keyword for selecting only single record
from countries table.
SELECT Top 1 name,population
FROM countries
order by population DESC

Return all Fields and Distinct Rows

Whats the best way to do this, when looking for distinct rows?
SELECT DISTINCT name, address
FROM table;
I still want to return all fields, ie address1, city etc but not include them in the DISTINCT row check.
Then you have to decide what to do when there are multiple rows with the same value for the column you want the distinct check to check against, but with different val;ues in the other columns. In this case how does the query processor know which of the multiple values in the other columns to output, if you don't care, then just write a group by on the distinct column, with Min(), or Max() on all the other ones..
EDIT: I agree with comments from others that as long as you have multiple dependant columns in the same table (e.g., Address1, Address2, City, State ) That this approach is going to give you mixed (and therefore inconsistent ) results. If each column attribute in the table is independant ( if addresses are all in an Address Table and only an AddressId is in this table) then it's not as significant an issue... cause at least all the columns from a join to the Address table will generate datea for the same address, but you are still getting a more or less random selection of one of the set of multiple addresses...
This will not mix and match your city, state, etc. and should give you the last one added even:
select b.*
from (
select max(id) id, Name, Address
from table a
group by Name, Address) as a
inner join table b
on a.id = b.id
When you have a mixed set of fields, some of which you want to be DISTINCT and others that you just want to appear, you require an aggregate query rather than DISTINCT. DISTINCT is only for returning single copies of identical fieldsets. Something like this might work:
SELECT name,
GROUP_CONCAT(DISTINCT address) AS addresses,
GROUP_CONCAT(DISTINCT city) AS cities
FROM the_table
GROUP BY name;
The above will get one row for each name. addresses contains a comma delimted string of all the addresses for that name once. cities does the sames for all the cities.
However, I don't see how the results of this query are going to be useful. It will be impossible to tell which address belongs to which city.
If, as is often the case, you are trying to create a query that will output rows in the format you require for presentation, you're much better off accepting multiple rows and then processing the query results in your application layer.
I don't think you can do this because it doesn't really make sense.
name | address | city | etc...
abc | 123 | def | ...
abc | 123 | hij | ...
if you were to include city, but not have it as part of the distinct clause, the value of city would be unpredictable unless you did something like Max(city).
You can do
SELECT DISTINCT Name, Address, Max (Address1), Max (City)
FROM table
Use #JBrooks answer below. He has a better answer.
Return all Fields and Distinct Rows
If you're using SQL Server 2005 or above you can use the RowNumber function. This will get you the row with the lowest ID for each name. If you want to 'group' by more columns, add them in the PARTITION BY section of the RowNumber.
SELECT id, Name, Address, ...
(select id, Name, Address, ...,
ROW_NUMBER() OVER (PARTITION BY Name ORDER BY id) AS RowNo
from table) sub
WHERE RowNo = 1