basic SQL queries - mysql

I just started to learn SQL and I have some queries to write to practise.
Can you help me and check it if it's correct?
I don't have an idea how to create three at the end
Let's assume that database is arbitrary. I just need to learn how to create those kind of queries to work on many diffrent databases.
-Specify the time from the system clock and the system clock date.
SELECT SYSDATETIME(),SYSDATETIMEOFFSET();
-Select employees that are in the age from 30 to 50 years.
SELECT * FROM employees
WHERE dateOfBirth BETWEEN DATE_SUB(NOW(), INTERVAL 30 YEAR)
AND DATE_SUB(date, INTERVAL 50 YEAR);
-Indicate in which department the employee works.
select employees.name, departments.name from employees where
employees.id_department=departments.id_department;
-Specify in what department the employee works and order in descending order and ascending order by name
select employees.name, departments.name from employees where
employees.id_department=departments.id_department ORDER BY Department DESC, Surname ASC;
-Specify in which department the employee works and order in descending order and ascending order by name limiting the number of tuples to chapters beginning with a or s.
-Is there a business department where no one is working?
View your net worker's salary, calculate your 18% tax rate and give you a tax deduction.

I'm new to this also. Would assume something like below:
select employees.name, departments.name from departments
Left Outer Join departments on departments.id_department = employees.id_department
WHERE employees.name IS NULL

Related

Subquery returns more than 1 row, how can I solve?

Question: Show the category of competitions that have always been hosted in the same country during May 2010. What is wrong with my query?
select Category
from competition
where Date >= '2010-01-01' and Date <= '2010-12-31'
group by Country, Category
having count(*) = (select count(*)
from competition
where Date >= '2010-01-01' and Date <= '2010-12-31'
group by Category)
You don't need two queries. Just use one query that checks that the count of countries is 1.
select category, count(DISTINCT country) AS country_count
from competition
where Date BETWEEN '2010-05-01' and '2010-05-31'
group by Category
HAVING country_count = 1
I also corrected the dates to be just May, not the whole year 2010.
Remove the GROUP BY if you that is making you return more than 1 row (in your HAVING CLAUSE. If you give me an example dataset and what you want I can help you more
I'd try something like this to start with:
SELECT COUNTRY
, CATEGORY
, COUNT(COUNTRY)
FROM COMPETITION
WHERE DATE BETWEEN '2010-04-30' AND '2010-06-01'
ORDER BY CATEGORY DESC, COUNT(COUNTRY) DESC
;
Your original query's date limits are just for the year of 2010 but you specified you only wanted May 2010. If the Date column is a date or datetime time you'll need to cast the string to the appropriate datatype.
Your question asked "always hosted by one country" - do you know that a competition is only going to be hosted by one country during that particular month? If you do, you're pretty much done. If you don't, however, then you need to clarify what your criteria really are

Query Between two date fields

I have one table of employees with a column called Hire Date. And I have another table of orders and every order has a date when it was processed.
Now I want to figure out how many orders this employee made in the first 30 days from his hire date. I made a query with DateAdd function in access and made a column with all employees 30 days after hire date, now I want to make a query of orders between hire date and 30 days after hire date.query from 30 days after hire date
Assume Employees table has EmpCode and Orders table has EmpCode too
It will be something like this
SELECT *
FROM Orders INNER JOIN Employees ON Orders.EmpCode = Employees.EmpCode
WHERE EmpCode = 'ABCD' AND DateAdd ( d, 30, Employees.HireDate) > Orders.OrdDate
Expand your query to include the EmployeeId. Then it could be:
Select
YourQuery.FirstName, YourQuery.LastName, Count(OrderTable.*) As OrderCount
From
YourQuery,
OrderTable
Where
OrderTable.EmplyoyeeId = YourQuery.EmplyoyeeId
And
OrderTable.OrderDate Between YourQuery.[Hire Date] And YourQuery.[30 days after]
Group By
YourQuery.FirstName,
YourQuery.LastName

Counting twice within one query

What am I doing wrong? Trying to output two COUNTs and need to Group by Department.
SELECT Department,
COUNT(DISTINCT ID) AS total,
SUM(CASE WHEN course LIKE 'AS%' THEN 1
ELSE 0
END) AS Total_AS
FROM schedule
GROUP BY Department
ORDER BY Department ASC
Only problem is that Total_As is counting Department for multiple instances. Just need to count once if employee(ID) took at least one training with Course AS%. The script is currently counting every single AS% taken by employee(ID). Need the case part to only count the employee(ID) once to indicate that employee took at least one AS% training or 0 if they did not attend. SUM should not count the employee more than once. Tried to use MAX in place of SUM but the results only gave 1 or 0 per Department. Trying to get output of Department, Total Employees, # of Employees in Department that have at least 1 Course Like 'AS%'.
Output should be:
Accounting, Total of 20 employees in Department, Total_AS 10.
Using current SUM, I get a result for Total_AS of 40 because 10 of the Employees(ID) took 4 courses each. Just need Total_AS to be COUNT of Employees who took at least 1 Course, which in this case would be 10.
Change the SUM to a COUNT(DISTINCT):
SELECT Department,
COUNT(DISTINCT ID) AS total,
COUNT(DISTINCT CASE WHEN course LIKE 'AS%' THEN id END) Total_AS
FROM schedule
GROUP BY Department
ORDER BY Department ASC

MySql - How to find out which month had the most prisoners added

I have two tables, prisoner and person.
Prisoner:
prisoner_id
person_ssn
sentence_start
sentence_end
Person
first_name
last_name
person_ssn
If the sentence_start field is of type DATE, is it possible for me to calculate which month has had the most prisoners added and then show that month and how many there were?
You simple need to run a COUNT query and GROUP the results by month and possibly year:
SELECT YEAR(sentence_start) AS Y, MONTH(sentence_start) AS M, COUNT(*) AS C
FROM prisoner
GROUP BY YEAR(sentence_start), MONTH(sentence_start)
It is also possible to use the MySQL EXTRACT function to obtain same results MUCH faster:
SELECT EXTRACT(YEAR_MONTH FROM sentence_start) AS YM, COUNT(*) AS C
FROM prisoner
GROUP BY EXTRACT(YEAR_MONTH FROM sentence_start)

MySql SUM and JOIN

I am trying to count sales made by a list of sales agents, this count is made every few minutes and updates a screen showing a 'sales leader board' which is updates using a Ajax call in the background.
I have one table which is created and populated every night containing the agent_id and the total sales for the week and month. I create a second, temporary table, on the fly which counts the sales for the day.
I need to combine the two tables to create a current list of sales for all agents in agent_count.
Table agent_count;
agent_id (varchar),
team_id (varchar),
name (varchar),
day(int),
week(int),
month(int)
Table sales;
agent_id (varchar),
day(int)
I can't figure out how to combine these tables. I think I need to use a join as all agents must be returned - even if they don't appear in the agent_count table.
First I make a simple call to get the week and month totals for all agents
SELECT agent_id, team_id, name, week, month FROM agent_count;
the I create a temporary table of todays sales, and then I count the sales for each agent for the day
CREATE TEMPORARY TABLE temp_todays_sales
SELECT s.id, s.agent_id
FROM sales s
WHERE DATEDIFF(s.uploaded, NOW()) = 0
AND s.valid = 1;
SELECT tts.agent_id, COUNT(tts.id) as today
FROM temp_todays_sales tts
GROUP BY tts.agent_id;
What is the best/easiet way to combine these to end up with a resultset such as
agent_id, team_id, name, day, week, month
where week and month also include the daily totals
thanks for any help!
Christy
SELECT s.agent_id, ac.team_id, ac.name,
s.`day` + COALESCE(ac.`day`, 0) AS `day`,
s.`day` + COALESCE(ac.`week`, 0) AS `week`,
s.`day` + COALESCE(ac.`month`, 0) AS `month`
FROM sales s
LEFT JOIN
agent_count ac
ON ac.agent_id = s.agent_id
team_id and name will be NULL if there is no record in agent_count for an agent.
If the agents can be missing from both tables, you normally would need to make a FULL JOIN but since MySQL does not support the latter you may use its poor man's substitution:
SELECT agent_id, MAX(team_id), MAX(name),
SUM(day), SUM(week), SUM(month)
FROM (
SELECT agent_id, NULL AS team_id, NULL AS name, day, day AS week, day AS month
FROM sales
UNION ALL
SELECT *
FROM agent_count
) q
GROUP BY
agent_id