How to make this 2 step query solution better - sql

Query is made in MS Access :
I show now a simplified example of my problem.
I have one table Members
Name/age/nickname
- Tom/12/wolf
- Chris/11/ranger
- Phil/14/H-man
- Chris/16/walker
- Chris/18/Mo
Goal: How many times a name occurs , but only count when the nickname had an "a" in it.
I needed 2 queries;
Step1:
SELECT Members.Name, Members.Age, Members.Nickname
FROM Members
WHERE (((Members.Nickname) Like "*A*"));
Step2:
SELECT Step1.Name, Count(Step1.Age) AS AantalVanAge
FROM Step1
GROUP BY Step1.Name;
Result
- Chris 2
- Phil 1

You can achieve this in a single query using:
select t.name, count(*) as AantalVanAge
from members t
where t.nickname like "*A*"
group by t.name

Use your 1st query as a subquery in the 2nd step:
SELECT t.Name, Count(t.Age) AS AantalVanAge
FROM (
SELECT Name, Age
FROM Members
WHERE Nickname Like "*A*"
) AS t
GROUP BY t.Name;

Related

Joining results from one query with another query

I have two queries. The first gives me a list of BusinessUnitIds along with a count for each:
SELECT [b].[BusinessUnitId], COUNT([b].[BusinessUnitId]) AS bucount
FROM [dbo].[ComponentTeamBusinessUnit] [b]
WHERE [b].[GlobalClientFiscalYearId] = #GlobalClientFiscalYearId
AND [b].[ComponentTeamId] IN (SELECT items FROM [dbo].[fnSplit](#ComponentTeamIds, ','))
GROUP BY [b].[BusinessUnitId])
I want to take the BusinessUnitIds in this result and join them to a second query which will retrieve the Business Unit Name associated with the BusinessUnitIds. Something like the following:
Select [c].Name, [first query result].Count from [dbo].[BusinessUnit] [c]
INNER JOIN [first query result]
WHERE [c].BusinessUnitId = [first query result].BusinessUnitId
Ultimately, what I want is a listing of Business Names, along with a count of each. I haven't been able to figure out how to do this. Can anyone help? To do both queries in a single statement would be tops. Thank you.
Exmaple:
SELECT [b].[BusinessUnitId],A.Name, COUNT([b].[BusinessUnitId]) AS bucount
FROM [dbo].[ComponentTeamBusinessUnit] [b]
LEFT JOIN NameTable as A
ON A.BusinessUnitId = b.BusinessUnitId
WHERE [b].[GlobalClientFiscalYearId] = #GlobalClientFiscalYearId
AND [b].[ComponentTeamId] IN (SELECT items FROM [dbo].[fnSplit](#ComponentTeamIds, ','))
GROUP BY [b].[BusinessUnitId],A.Name
If tables are One to One, will be neat, if one to many, you will see the result like:
id name count
1 A 5
1 B 6
And if you want to group id 1, to get:
id name count
1 A,B 11
That you need to use FOR XML PATH() together with STUFF, or STRING_SPLIT, really depends on your real case.

Return all rows with MAX value based on the calculation done on two columns

I have a table named 'Houses' which contains fields 'house_id', 'house_type', 'bhk_detail', 'bed_count', 'furnishing_type', 'Beds_vacant'. Now i need to write a query to get the house details of the house having highest occupancy which bed_count - bed_vacant. I tried something like this:
SELECT hs.house_id, hs.house_type , hs.bhk_details, hs.bed_count , hs.furnishing_type, hs.Beds_vacant,
max(hs.bed_count - hs.Beds_vacant
FROM Houses as hs
GROUP BY hs.house_id, hs.house_type, hs.bhk_details, hs.bed_count, hs.furnishing_type, hs.Beds_vacant
HAVING MAX(hs.bed_count - hs.Beds_vacant)IN (SELECT max(hs.bed_count - hs.Beds_vacant) FROM Houses as hs)
The query worked for me but i was wondering if we can write it more precisely
I think the simplest way is top 1 with ties:
select top (1) with ties h.*
from Houses h
order by (h.bed_count - h.beds_vacant) desc;

compare records within same table

I have Student_Table with following structure.
Student_Note Table
student_id seq_num note
11212 1 firstnote
11212 2 secondNote
11212 3 thirdNote
21232 1 secondstudentnote1
21232 2 secondstudentnote2
so on
I want to get latest note (which has largest seq_num) for a particilar student.
I have tried following query
select tn.note from Student_Note tn JOIN Student_Note tn1
ON (tn.student_id =tn1.student_id AND tn.seq_num < tn1.seq_num)
where tn.student_id=11212
it is giving more than one row. How to achieve aforementioned scenario ?
I forgot mention that I am using above query as subquery . As per sybase TOP clause will not work in subquery.
P.S. I am using sybase.
OK - changed as apparently cannot use TOP.........
select tn.note from Student_Note tn
where tn.student_id=11212
and tn.seq_num = (SELECT MAX(seq_num) from Student_Note WHERE Student_Note.Student_Id = tn.Student_Id)
Please try this
select substring(max(str(seq_num,10,'0') + note),11,len(note))
from Student_Note
where student_id=11212

find more than one word in same row

Query to generate a list of companies that have “prior to” more than once in their names.
For Example:
Company Name
Ittal PLC (adz ll **prior to** 04/2012) (Z Amp C **prior to** 02/2009)
One simple way is to use like:
where CompanyName like '%prior to%prior to%'
Try this
select *
from Yourtable
where len([Company Name]) - len(replace([Company Name],'prior to','')) > 1
and len([Company Name]) - len(replace([Company Name],'prior to','')) <> len('prior to')
SQL FIDDLE DEMO
I'd probably implement this as a two-step process.
1) Find all records matching prior to.
E.g.
SELECT Company_name FROM COMPANY_TABLE WHERE Company_name LIKE '%prior to%'
2) Iterate through all the records and find only those that have 2 occurrences of the prior to substring (in whatever language you're using).

Only a single result allowed for a SELECT that is part of an expression

I have the following SQL statement. It's throws the following error: "Only a single result allowed for a SELECT that is part of an expression". The goal of my sql statement is to get the name of the employee who made the 'cheapest' bribe.
The part between the brackets return the employee_id and the money it costs a day (of the relative cheapest bribe). These are two results while I only want the employee_id. So I just want to use the MIN part to get the right employee_id. How can I do this?
SELECT Voornaam, Achternaam
FROM Medewerker m JOIN
(
SELECT Medewerker_id
FROM Steekpenning
ORDER BY -1*Bedrag/(julianday(Begindatum) - julianday(Einddatum))
limit 1
) s
on m.Medewerker_id = s.Medewerker_id;
EDITED the answer. How can I expand this query to only show the bribes started this month? I think I need to use something like this? (julianday(Begindatum) - julianday('now')) > 31 but where?
Regards.
Cas
I think the following will work in SQLite:
select Firstname, Surname
from Employee e join
(select employee_id
from bribe
order by -1*Amount/(julianday(Startdate) - julianday(Enddate))
limit 1
) b
on e.employee_id = b.employee_id;