Ambiguous column name - whats wrong with the syntax here? - sql

I cant seem to figure out what is wrong with the SQL here, when an asterisk (*) is included in the SELECT statement. eg:
SELECT firstname, lastname, createdon, * from Person
Where firstname like '%J%'
Order By createdon desc
I get 'Ambiguous column name 'CreatedOn'. error.
However without the (*) where its not returning the remainder of the columns it works fine.
Any suggestion or workaround?

createdon is in the returned dataset twice, once from the explicit call, and once from the *. As such there are 2 columns with the name createdon and so ORDER BY createdon is ambiguous; do you want to order by the first column named createdon or the second one (the fact that they would have same value is irrelevant, as SQL Server just sees 2 columns with the same name).
Really, you shouldn't be using SELECT * and should be defining all your columns; I don't see a need to return 3 of columns twice. But what you can do if you "must" have 2 copies of the same column is to prefix the one in the ORDER BY with the table name/alias; this would then refer to the column "in" the table, not the one in the result set (of which there are 2). I use an alias here:
SELECT P.firstname,
P.lastname,
P.createdon,
* --Replace this with the actual columns you need, don't be lazy
FROM dbo.Person P
WHERE P.firstname like '%J%'
ORDER BY P.createdon DESC;

In your query, you are selecting "createdon" column twice and but ordering the results by "one of them. The SQL interpreter doesn't understand which "createdon" column it needs to sort the result and so Ambiguous column name is returned. You can solve this by using aliasing one of the "createdon" in the selected statement.

im not sure but try with that
SELECT firstname, lastname, createdon createdon2, * from Person
Where firstname like '%J%'
Order By createdon 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

Clarification on database architecture question

I'm working on a quiz for this internship and one question is worded strangely. I'm hoping that one of you could help me find clarification.
Context: I've just created a flat-file table (database), and added 4 columns (UserId,firstname,lastname,email). I filled each column with 15 rows of made-up data.
The question states "Query all rows in the firstname column that start with the letter B and ordered by the lastname column in descending order."
I'm not sure what they're asking for, does this make sense to you?
The question is asking you to query the table, selecting the firstname column and all data that starts with the letter 'B'. And then ordered by the lastname. It's a fairly basic query:
SELECT t.firstname
FROM tablename t
WHERE t.firstname like 'B%'
ORDER BY t.lastname DESC;
EDIT: I did forget the DESC;
The query consists in retrieving first names and last names of rows where the firstname starts with the letter B, and then to order the resulting set using the lastname field in descending order.
The query in sql would be like:
SELECT firstname, lastname FROM users WHERE firstname LIKE 'B%' ORDER BY lastname DESC;

How to insert a count column into a sql query

I need the second column of the table retrieved from a query to have a count of the number of rows, so row one would have a 1, row 2 would have a 2 and so on. I am not very proficient with sql so I am sorry if this is a simple task.
A basic example of what I am doing would be is:
SELECT [Name], [I_NEED_ROW_COUNT_HERE],[Age],[Gender]
FROM [customer]
The row count must be the second column and will act as an ID for each row. It must be the second row as the text file it is generating will be sent to the state and they require a specific format.
Thanks for any help.
With your edit, I see that you want a row ID (normally called row number rather than "count") which is best gathered from a unique ID in the database (person_id or some other unique field). If that isn't possible, you can make one for this report with ROW_NUMBER() OVER (ORDER BY EMPLOYEE_ID DESC) AS ID, in your select statement.
select Name, ROW_NUMBER() OVER (ORDER BY Name DESC) AS ID,
Age, Gender
from customer
This function adds a field to the output called ID (see my tips at the bottom to describe aliases). Since this isn't in the database, it needs a method to determine how it will increment. After the over keyword it orders by Name in descending order.
Information on Counting follows (won't be unique by row):
If each customer has multiple entries but the selected fields are the same for that user and you are counting that user's records (summed in one result record for the user) then you would write:
select Name, count(*), Age, Gender
from customer
group by name, age, gender
This will count (see MSDN) all the user's records as grouped by the name, age and gender (if they match, it's a single record).
However, if you are counting all records so that your whole report has the grand total on every line, then you want:
select Name, (select count(*) from customer) as "count", Age, Gender
from customer
TIP: If you're using something like SSMS to write a query, dragging in columns will put brackets around the columns. This is only necessary if you have spaces in column names, but a DBA will tend to avoid that like the plague. Also, if you need a column header to be something specific, you can use the as keyword like in my first example.
W3Schools has a good tutorial on count()
The COUNT(column_name) function returns
the number of values (NULL values will not be counted) of the
specified column:
SELECT COUNT(column_name) FROM table_name;
The COUNT(*) function returns the number of records in a table:
SELECT COUNT(*) FROM table_name;
The COUNT(DISTINCT column_name) function returns the number of
distinct values of the specified column:
SELECT COUNT(DISTINCT column_name) FROM table_name;
COUNT(DISTINCT) works with ORACLE and Microsoft SQL Server, but
not with Microsoft Access.
It's odd to repeat the same number in every row but it sounds like this is what you're asking for. And note that this might not work in your flavor of SQL. MS Access?
SELECT [Name], (select count(*) from [customer]), [Age], [Gender]
FROM [customer]

Can't get unique values

I'm using my sql to get unique values from database
My query looks as follows, but somehow I'm not able to get unique results
SELECT
DISTINCT(company_name),
sp_id
FROM
Student_Training
ORDER BY
company_name
sp_id is the primary key, and then company_name is the companies name that needs to be unique
looks as follows
sp_id, company_name
1 comp1
2 comp2
3 comp2
4 comp3
Just not sorting this unique
DISTINCT works globally, on all the columns you SELECT. Here you're getting distinct pairs of (sp_id, company_name) values, but the individual values of each column may show duplicates.
That being said, it's extremely deceiving that MySQL authorizes the syntax SELECT DISTINCT(company_name), sp_id when it really means SELECT DISTINCT(company_name, sp_id). You don't need the parentheses at all, by the way.
Edit
Actually there's a reason why DISTINCT(company_name), sp_id is valid syntax: adding parentheses around an expression is always legal although it can be overkill: company_name is the same as (company_name) or even (((company_name))). Hence what that piece of SQL means is really: “DISTINCT [company_name in parentheses], [sp_id]”. The parentheses are attached to the column name, not the DISTINCT keyword, which, unlike aggregate function names, for example, does not need parentheses (AVG sp_id is not legal even if unambiguous for a human reader, it's always AVG(sp_id).)
For that matter, you could write SELECT DISTINCT company_name, (sp_id) or SELECT DISTINCT (company_name), (sp_id), it's exactly the same as the plain syntax without parentheses. Putting the list of columns inside parentheses – (company_name, sp_id) – is not legal SQL syntax, though, you can only SELECT “plain” lists of columns, unparenthesized (the form's spell-checker tells me this last expression is not an English word but I don't care. It's Friday afternoon after all).
Therefore, any database engine should accept this confusing syntax :-(
DISTINCT will make unique rows, meaning the unique combination of the field values in your query.
The following query will return a list of all the unique company_name together with the first match for sp_id.
SELECT sp_id, company_name
FROM Student_Training
GROUP BY company_name
And as Arthur Reutenauer has suggested, it is indeed pretty deceiving that MySQL allows the DISTINCT(fieldname) syntax when it actually means DISTINCT(field1, field2, ..., fieldn)
Which id you want in case when a single company_name has two or more id's?
This:
SELECT DISTINCT company_name
FROM Student_Training
will select only the company_name.
This:
SELECT company_name, MIN(id)
FROM Student_Training
GROUP BY
company_name
will select minimal id for each company name.
DISTINCT does not work the way you think it does. It gives you a distinct record. Stop and think about how it could return what you expect it to return. If you had a table as follows
id name
1 joe
2 joe
3 james
If it only returned distinct names, which id would it return for joe?
You may want
SELECT company_name, Min(sp_id) FROM Student_Tracking GROUP BY company_name
or perhaps (as above) just
SELECT DISTINCT company_name from student_training

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