Can't figure this error out? - sql

Code :
SELECT * FROM Grade
WHERE grade = ‘MG’ ‘1-9’
SELECT * StaffNo, Name, DOB, ReportsTo,
FROM Staff
ORDER BY DOB DESC;
I keep getting
ORA-00911: invalid character
is this a problem with the code?

Couple of problems -
1.You either need to do a UNION between the first and second SELECT statement, in which case the columns (datatypes) on both the SELECTs should match. Also, one of the columns should be DOB
SELECT StaffNo, Name, DOB, ReportsTo --you can do * here if Grade has exactly 4 columns of same datatype as in columns in the select below
FROM Grade
WHERE grade IN ('MG', '1', '9') --Check for Missing grade or grade 1 or grade 9
UNION
SELECT StaffNo, Name, DOB, ReportsTo
FROM Staff
ORDER BY DOB DESC;
Or these are two entirely different queries like-
SELECT * FROM Grade
WHERE grade IN ('MG','1', '9');
SELECT StaffNo, Name, DOB, ReportsTo --* means all columns so its either * or just the column name specifically. Both can be done, but doesn't make sense
FROM Staff
ORDER BY DOB DESC;
2.’ is a wrong character in Oracle, it should rather be '.
3.In the second SELECT the column ReportsTo ends with a ,. This will be considered illegal by Oracle.

This is the problem, for potentially two reasons:
WHERE grade = ‘MG’ ‘1-9’
Have you actually included curly quotes in your query? If so, that's probably why Oracle is complaining about an invalid character.
However, it's then unclear exactly what you're trying to match. Do you want anything starting with MG and then a character between 1 and 9? If so, you could use:
WHERE grade BETWEEN 'MG1' AND 'MG9'
If that's not what you mean, you need to explain what you're trying to do more carefully - and understand that if a human can't understand your intention, it's even less likely that a SQL parser will...

Related

how do I make a good subquery in SQL in this code

I need a bit of help with an SQL statement, pretty much a beginner so just go easy on me.
The Program want me to give out every Student who studied for less than 7 years at a School
Select schoolid, characterid, firstname, lastname, count(year) as num
from schoolhouse natural join student natural join character
group by schoolid, characterid, firstname, lastname
So far, so good, with this code I can already see a relation with the counted years but I can't make a where statement which includes the "num" count from the select statement.
WHERE clauses are applied to the individual rows after the tables are joined, but before they are grouped/aggregated. HAVING clauses are used to assert conditions on the results of the aggregation. Just add HAVING count(year) < 7
Select schoolid, characterid, firstname, lastname, count(year) as num
from schoolhouse natural join student natural join character
group by schoolid, characterid, firstname, lastname
having count(year) < 7
But also always qualify which table your columns come from. In this query it's not clear if the year column is from the schoolhouse table, the student table or the character table.
It should look more like...
SELECT TABLE.schoolid, TABLE.characterid, TABLE.firstname, TABLE.lastname, COUNT(TABLE.year) AS num
FROM schoolhouse NATURAL JOIN student NATURAL JOIN character
GROUP BY TABLE.schoolid, TABLE.characterid, TABLE.firstname, TABLE.lastname
HAVING COUNT(TABLE.year) < 7
(Replacing each occurance of TABLE with the correct table name for each case.)
Finally, using words such as character and year as column or table names is usually frowned upon. Such words ofter appear as "key-words" in SQL and can cause errors or ambiguity. In general, if something even might appear as an SQL key-word, don't use it as a column or table name.

Using CASE statement along with SELECT in SQLite to exclude displaying certain results

I was trying to solve the problem of "The number of people of each gender there are in the database, where the gender is known, display the count of people against each gender" in SQLite. I typed a query
SELECT sex, COUNT(name) from employee_table GROUP BY sex ORDER BY sex DESC;
which is partially correct as it showed as output the number of males and females. But, it also shows the number of blank entries which were neither classified as Male or Female.
I have to stop displaying the count of the blank entries. I guess for this, I have to use a CASE statement. I tried CASE statement in different ways. But those didn't work. I tried searching the internet and stack overflow and tried those methods. Those also didn't work.
Any help would be appreciated.
Thanks,
Richard
You want to filter the results and a case expression doesn't do that. Without sample data, it is difficult to say exactly what the expression is, but perhaps:
SELECT sex, COUNT(name)
FROM employee_table
WHERE sex IS NOT NULL
GROUP BY sex
ORDER BY sex DESC;
If the "blank" results are really empty strings, then that would be:
WHERE sex <> ''
This also filters out NULL values.
Or if you want explicit values, then you can use IN:
WHERE sex IN ('m', 'f')

Count how many employees with the same name exist in the database in PostgreSQL

I have a data table of employees, I want to get how many same name employees in the database. Name information is saved as first_name and last_name. I have tried.
Select count(concat(first_name,'',last_name) as empname, (concat(first_name,'',last_name) as empname from xyz.
getting error.
Your SQL is missing some parentheses (brackets), and to use an aggregation function as well as a non-aggregated column, you must include the non-aggregated column in a GROUP BY
So your SQL should look like this:
Select count(concat(first_name,' ',last_name)) as countempname,
(concat(first_name,' ',last_name)) as empname
from xyz
GROUP BY (concat(first_name,' ',last_name));
Notice also that I added a space. It is a bit odd to include an empty string in the concat. Also as a short form, if you do not want to repeat the concat in the GROUP BY, you can replace it with the column ordinal number (in this case 2) so it becomes:
Select count(concat(first_name,' ',last_name)) as countempname,
(concat(first_name,' ',last_name)) as empname
from xyz
GROUP BY 2;
If you want to count how many times each first/last name tuple appears in the table, you can use aggregation:
select first_name, last_name, count(*) cnt
from xyz
group by first_name, last_name
This gives you one row per first/last name tuple, with the total count. Note that there is not point concatenating the variables; group by can operate of column tuples.
On the other hand, maybe you want the entire employee row, with an additional column that holds the total count of other rows having the same names. If so, you can use a window count instead of aggregation:
select x.*, count(*) over(partiton by first_name, last_name) cnt
from xyz

Microsoft SQL server select statements on multiple tables?

so I've been struggling with some of the select statements on multiple tables:
Employee table
Employee_ID
First_Name
Last_Name
Assignment table
Assignment_ID
Employee_ID
Host_Country_arrival_Date
Host_Country_departure_Date
Scheduled_End_Date
I'm being asked to display query to display employee full name, number of days between the host country arrival date and host country departure date, number of days between today's date and the assignment scheduled end date and the results sorted according to host country arrival date with the oldest date on top.
also, I'm not familiar with the sort function in SQL server..
Here's my query and I've been getting syntax errors:
SELECT
First_Name
Last_Name
FROM Employee
SELECT
Host_Country_Arrival_Date
Host_Country_Departure_Date
FROM Assignment;
So, Basically what your code is doing is 2 different queries. The first getting all the employees names, and the second one getting the dates of the assignments.
What you'll want to do here is take advantage of the relationship between the tables using a JOIN. That is basically saying "Give me all employees and all of HIS/HERS assignments". So, for each assignment that the employee has, it will bring a row in the result with his name and the assignment info.
To get the difference between days you use DATEDIFF passing 3 parameters, the timespan in which to calculate the difference, the first and the second date. It will then Subtract the first one from the second one and give you the result in the selected timespan.
And finnaly the sorting: Just add 'ORDER BY' followed by each column that you want to use for ordering and then specify if you want it ascending (ASC) or descending (DESC).
You can check how I would answer the if that question was proposed to me in a coding challenge.
SELECT
CONCAT(E.First_Name,' ', E.Last_Name) FullName,
DATEDIFF(DAY,Scheduled_End_Date,getdate()) DaysTillScheduledDate,
DATEDIFF(DAY,Host_Country_Arrival_Date,Host_Country_Departure_Date) DaysTillScheduledDate
FROM Employee As E --Is nice to add aliases
Inner Join
Assignment As A
on E.Employee_ID = A.Employee_ID -- Read a little bit about joins, there are a lot of material availabel an its going to be really necessary moving forward with SQL
order by Host_Country_Arrival_Date DESC -- Just put the field that you want to order by here, desc indicates that it should be descending
You should use a JOIN to link the tables together on Employee_ID:
SELECT
First_Name,
Last_Name,
Host_Country_Arrival_Date,
Host_Country_Departure_Date
FROM Employee
JOIN Assignment ON Assignment.Employee_ID = Employee.Employee_ID;
What this is saying basically is that for each employee, go out to the assignments table and add the assignments for that employee. If there are multiple assignments, the employee columns will be repeated on each row with the assignment columns for the assignment.
You need to look for the join and group by. Please find this link for reference tutorial
For now you may try this...
SELECT
CONCAT(Emp.First_Name,' ', Emp.Last_Name) FullName,
DATEDIFF(DAY,Scheduled_End_Date,getdate()) DaysTillScheduledDate,
DATEDIFF(DAY,Host_Country_Arrival_Date,Host_Country_Departure_Date) DaysTillScheduledDate
FROM Employee As Emp Inner Join Assignment As Assign on Emp.Employee_ID = Assign.Employee_ID
order by Host_Country_Arrival_Date DESC

Having trouble with Distinct(Coloumn_name)

I'm having problems with getting the correct data from my tables.
I've got a table with information on customers sending letters.
My table have following coloumbs( Name, Postalcode, Country, Phone_number, Letters(The number of letters))
I want to get the numbers of letters send from every customer, depending on the Postal_code.
Select Distinct(Postal_Code), Count(*)
from Table_name
Group by Postal_Code, Letters
The result of this, is not exactly what I wanted, because I get duplicates of the postalcode, and the numbers of letters are wrong.
I'm pretty new to this stuff, so I hope someone can help me.
EDIT:
At the moment, i'm trying to get a date on the record, and my code i slike this now.
Select Postal_Code, Sum(Letters), To_Char(trunc(Start_time),'DD-MM-YYYY') AS StartTime
from Table_name
Group by Postal_Code
But I get an error when running it. The error says: ORA-00937: not a single-group group function.
I have googlet the problem, and tried with my start_time in the group by, but this gives me the wrong result.
If you use GROUP BY you don't need DISTINCT. Since letters is a number you need to SUM() them. So total letters for each postal code would be something along the lines of:
Select Postal_Code, SUM(letters)
from Table_name
Group by Postal_Code
GROUP BY gives you distinct values for all the columns in the clause. So grouping by POSTAL_CODE, LETTERS is why you get duplicate POSTAL_CODE values.
Not sure I completely understand what you're trying to do, but here is my interpretation:
Select Postal_Code
, sum(letters) no_of_letters
, Count(*) no_of_customers
from Table_name
Group by Postal_Code