Generate the following two result sets:
1). Query an alphabetically ordered list of all names in OCCUPATIONS, immediately followed by the first letter of each profession as a parenthetical (i.e.: enclosed in parentheses). For example: AnActorName(A), ADoctorName(D), AProfessorName(P), and ASingerName(S).
2). Query the number of ocurrences of each occupation in OCCUPATIONS. Sort the occurrences in ascending order, and output them in the following format:
There are total [occupation_count] [occupation]s.
Table Name: Occupations
Total Columns: Two = 'Name' and 'Occupation', demo table is shown below:
Sample Output:
Ashely(P)
Christeen(P)
Jane(A)
Jenny(D)
Julia(A)
Ketty(P)
Maria(A)
Meera(S)
Priya(S)
Samantha(D)
There are total 2 doctors.
There are total 2 singers.
There are total 3 actors.
There are total 3 professors.
My Approach:
(SELECT NAME, '(', SUBSTRING(OCCUPATION, 1, 1), ')'
FROM OCCUPATIONS ORDER BY NAME)
UNION ALL
(SELECT COUNT(*) FROM OCCUPATIONS GROUP BY OCCUPATION ORDER BY ASEC);
Error:
ERROR 1222 (21000) at line 1:
The used SELECT statements have a different number of columns
Thank You!
Sometimes on HackerRank concat functon will give an error. You can use || to seperate in the same way.
So if the code below doesnt work for you:
(
SELECT CONCAT(NAME, '(', SUBSTRING(OCCUPATION, 1, 1), ')') as THETEXT, '1' as SELECTNUMBER
FROM OCCUPATIONS
)
UNION ALL
(
SELECT CONCAT('There are total ', COUNT(*),' ', OCCUPATION, (IF (COUNT(*) > 1, 's',''))) as THETEXT, '2' as SELECTNUMBER
FROM OCCUPATIONS GROUP BY OCCUPATION
)
ORDER BY SELECTNUMBER ASC, THETEXT ASC;
TRY THIS INSTEAD!
SELECT name || '(' || UPPER(SUBSTR(occupation, 1, 1)) || ')' FROM occupations ORDER BY name;
SELECT 'There are a total of' || ' ' || COUNT(occupation) || ' ' || LOWER(occupation) || 's' || '.' FROM occupations GROUP BY occupation ORDER BY COUNT(occupation) ASC;
I just tried on hackerrank and it works, You don't need to use Union.
select concat(name,'(',upper(substring(occupation,1,1)),')') from occupations
order by name;
select concat("There are a total of",' ',count(occupation),' ',lower(occupation),'s',".") from occupations
group by occupation
order by count(occupation) asc;
SELECT concat(NAME,concat("(",LEFT(occupation,1),")"))
FROM OCCUPATIONS
ORDER BY NAME ASC;
select CONCAT("There are a total of", " ",COUNT(occupation), " ",LCASE(occupation),"s",".")AS stat
from OCCUPATIONS
group by occupation
order by COUNT(occupation) ASC,occupation
Worked on hackerrank
SELECT Name || '(' || SUBSTR(Occupation,1,1) || ')'-- AS THETEXT, '1' AS SELECTNUMBER
FROM OCCUPATIONS
order by Name;
SELECT 'There are a total of' || ' ' || COUNT(*) || ' ' || lower(Occupation) || 's.'
FROM OCCUPATIONS GROUP BY OCCUPATION
ORDER BY COUNT(Occupation), lower(Occupation);
union requires the two queries have the same number of columns, you can add any some columns to the second query to make them like the first one like SELECT COUNT(*), 'col-1', 'col-2', 'col-3' from
//Just be careful for the format!
(select concat(name, '(',left(occupation,1),')') as text
from occupations
)
union all
(
select concat(
'There are total ',
count(*), ' ', lower(occupation),
case
when COUNT(*) > 1
then 's'
end
,
'.'
) as text
from occupations
group by occupation
)
order by text asc;
(
SELECT CONCAT(NAME, '(', SUBSTRING(OCCUPATION, 1, 1), ')') as THETEXT
FROM OCCUPATIONS
)
UNION ALL
(
SELECT CONCAT('There are total ', COUNT(*),' ', LOWER(OCCUPATION) ,(IF (COUNT(*) > 1, 's','')), '.') as THETEXT
FROM OCCUPATIONS group by OCCUPATION
)
ORDER by THETEXT ASC;
This worked for me on MySQL
select concat(name,"(",substr(occupation,1,1),")") from occupations
order by name asc;
select concat('There are total ',count(*),' ',lower(occupation),'s.') as n from occupations
group by occupation
order by n asc;
select concat(name,'(',left(occupation,1),')') from occupations order by name;
select concat('There are total of',' ',count(occupation),' ',lower(occupation),"s.") from occupations group by occupation order by count(occupation),occupation;
(Select name||'('||substr(Occupation,0,1)||')'
from OCCUPATIONS)
Union All
(Select 'There are a total of '||count(*)||' '||lower(Occupation)||'s.'
from OCCUPATIONS group by Occupation)
order by 1;
SELECT CONCAT(name, '(', SUBSTRING(occupation, 1, 1), ')') as occ from occupations ORDER BY name;
SELECT concat('There are a total of ', COUNT(*), ' ', LCASE(occupation), 's.') from occupations GROUP BY occupation ORDER BY COUNT(*), occupation;
This does the charm.
SELECT CONCAT(NAME ,'('||SUBSTR(occupation,1,1)||')')
FROM occupations
ORDER BY NAME ASC;
SELECT CONCAT('There are a total of ',COUNT (occupation)||' '||LOWER(occupation)||'s.')
FROM occupations
GROUP BY occupation
ORDER BY COUNT(occupation),occupation ASC;
This works for me:
select CONCAT(name,'(',left(occupation,1),')')
from OCCUPATIONS
order by name;
select CONCAT('There are a total of',' ',count(occupation),' ',lower(occupation),'s.')
from OCCUPATIONS
group by occupation
order by count(occupation), occupation;
SELECT CONCAT(NAME,'(',LEFT(OCCUPATION,1),')')
FROM OCCUPATIONS ORDER BY NAME;
SELECT CONCAT("There are total of ",COUNT_OCCUPATION," ",OCCUPATION,".")
FROM
(SELECT COUNT(OCCUPATION) AS COUNT_OCCUPATION,OCCUPATION
FROM OCCUPATIONS
GROUP BY OCCUPATION
ORDER BY COUNT_OCCUPATION ASC,OCCUPATION ASC) AS OCP
select CONCAT(NAME, '(', left(OCCUPATION,1),')') from OCCUPATIONS ORDER BY NAME;
select CONCAT("There are a total of ", count(OCCUPATION), " ", lower(OCCUPATION),(if(count(OCCUPATION) >1,"s","")), ".") from OCCUPATIONS group by occupation order by count(OCCUPATION), OCCUPATION;
select concat(name, '(',substring(occupation,1,1),')') from OCCUPATIONS order by name;
select concat('There are a total of ',count(occupation),' ',lower(occupation),'s.') as 'sentence' from OCCUPATIONS group by occupation order by count(occupation), occupation,field(occupation,'doctor','singer','actor','professor');
check below code. hope this helps its 100% working
select concat(Name,"(",left(Occupation,1),")")
from occupations
order by Name;
select concat("There are a total of ",count(Occupation),' ',lower(occupation),"s.")
from Occupations
group by occupation
order by count(Occupation)asc, Occupation;
/* sort answer is here */
( select concat(name,'(',left(occupation,1),')') as ocps from
Occupations) union
(select distinct concat('There are a total of
',count(occupation),' ',lower(occupation),'s.') from Occupations
group by occupation)order by ocps;
select Name+'('+substring(Occupation,1,1)+')' from occupations order by name asc;
select concat('There are a total of',' ', count(occupation),' ',Lower(occupation),'s','.') from Occupations group by Occupation order by count(occupation), occupation asc
One can make use of the UNION operator in MySQL to union each part of the question.
NOTE: To combine the column names into one column the CONCAT() function can be used.
SELECT DISTINCT CONCAT(name, '(', left(occupation, 1), ')') AS n
from OCCUPATIONS
union
select concat('There are a total of ', (select count(*) from OCCUPATIONS group by occupation having occupation = 'doctor'), ' doctors.')
union
select concat('There are a total of ', (select count(*) from OCCUPATIONS group by occupation having occupation = 'singer'), ' singers.')
union
select concat('There are a total of ', (select count(*) from OCCUPATIONS group by occupation having occupation = 'actor'), ' actors.')
union
select concat('There are a total of ', (select count(*) from OCCUPATIONS group by occupation having occupation = 'professor'), ' professors.')
order by n asc;
select concat(Name,'(',substring(Occupation,1,1),')') from OCCUPATIONS order by Name;
select
concat('There are a total of ',count(*),' ',LCASE(Occupation),
If(count(*)>1,'s.',''))
from OCCUPATIONS group by Occupation order by count(*) ASC
;
Please follow this code for Mysql. This works best for me. I have tried and got the correct results.
select concat(name,'(',left(occupation,1),')') from occupations
order by name;
select concat('There are a total of ',count,' ',lower(occupation),'s.') from (select occupation, count(*) as count from occupations group by occupation)a
order by count, occupation;
For first query, I have concat the column 'name' with brackets and 1st char of value in column occupation. later order by is arranging them in ascending order (by default it is in ascending order).
second query, order by count(occupation) was not working for me so to solve this, i have used nested queries. Query in bracket is providing me occupation column, count of occupation when it is group by. then i concat the string with count and occupation name. later order by count in ascending order. Further if count is same for 2 occupations , so used order by occupation too to arrange them in ascending order.
Thanks
SELECT concat(name,'(',left(occupation,1),')')
FROM occupations
ORDER BY name;
SELECT concat('There are a total of ',cnt,' ',lower(occupation),'s.') FROM (
SELECT occupation,count(occupation) as cnt
FROM occupations
GROUP BY occupation
) a
ORDER BY cnt,occupation;
You can use in this way:
SELECT CONCAT(NAME,"(",SUBSTRING(Occupation, 1, 1),")") FROM OCCUPATIONS ORDER BY NAME
SELECT CONCAT("There are a total of"," ",COUNT(Occupation),
" ",LOWER(Occupation),"s",".") FROM OCCUPATIONS GROUP BY Occupation ORDER BY COUNT(Occupation),Occupation
This works too, no need of union as they are asking for 2 separate queries
select name||'('||substr(occupation,1,1)||')' from occupations order by name;
select 'There are a total of ',cnt,decode(occ,'P','professors','D','doctors',
'S','singers','A','actors')||'.'
from
(select distinct(substr(occupation,1,1)) as occ,count(*) as cnt from occupations group by substr(occupation,1,1)) order by cnt,occ;
select concat(name,"(",substring(occupation, 1, 1), ")") from occupations order by name;
select concat("There are a total of ", count(Occupation), " ", lower(occupation), "s.") from occupations group by occupation order by count(Occupation), Occupation;
select concat(Name,'(',upper(substr(Occupation,1,1)),')') from OCCUPATIONS order by Name;
select concat('There are a total of',' ',count(Occupation),' ',lower(Occupation),'s','.') from OCCUPATIONS group by Occupation order by count(Occupation) asc,lower(Occupation);
P.S--- LOOK AT THE SECOND QUERY...ADD A FULLSTOP
This works on Hacker rank, check this out
(select concat(name,'(',substr(occupation,1,1),')') N
from OCCUPATIONS)
union
(select concat('There are a total of ',count(occupation),' ',lower(occupation),'s.') from
occupations
group by occupation)
order by N asc;
WITH t1 AS (SELECT name,
LEFT(occupation,1) AS firstletter
FROM occupations
ORDER BY 1)
SELECT CONCAT(name, '(', firstletter, ')') AS result
FROM t1;
WITH t2 AS (SELECT occupation,
COUNT(occupation) AS occupation_count
FROM occupations
GROUP BY 1
ORDER BY 2,1)
SELECT CONCAT('There ','are ','a ','total ','of ',occupation_count,' ' ,LOWER(occupation),'s','.')
FROM t2;
I have broken the question down into two CTE(Common table expression) which are temporary tables. The first CTE(t1) selects the occupation table for name, selects the first letter of the data in occupation column using "LEFT()" function then orders alphabetically by name as required by the question. The select statement then queries the CTE(t1) using "CONCAT()" function to obtain its result.
CTE(t2) selects occupation, "COUNT()", group by occupation and order by occupation count and occupation. the select statement then queries t2 using "CONCAT()"
SELECT CONCAT(NAME,"(",LEFT(OCCUPATION,1),")") FROM OCCUPATIONS
ORDER BY NAME;
SELECT CONCAT("There are a total of ",COUNT(OCCUPATION)," ",lower(OCCUPATION),"s.")
FROM OCCUPATIONS
GROUP BY OCCUPATION
ORDER BY COUNT(OCCUPATION);
Related
this is the code the result is not ordered
(select concat (name,"(",left(OCCUPATION,1),")")
from OCCUPATIONS
order by name asc
) union
(select concat ("there are a total of ",count(OCCUPATION)," ",OCCUPATION, "s.")
from OCCUPATIONS
group by OCCUPATION
order by count(OCCUPATION) asc,OCCUPATION asc
)
enter image description here
SELECT DISTINCT OCCUPATION, COUNT(*)
FROM OCCUPATIONS
GROUP BY OCCUPATION
ORDER BY COUNT(*), OCCUPATION ASC;
Above query will give me unique Occupation and their count in ascending order of their occurrence. Now I want to use the result to print statement
There are a total of [occupation_count] [occupation]s.
I tried this
SELECT CONCAT('There are a total of ', COUNT(*), DISTINCT OCCUPATION, 's.')
FROM OCCUPATIONS
GROUP BY OCCUPATION
ORDER BY COUNT(*), OCCUPATION ASC;
but I got syntax error.
for each distinct occupation.
How can I do this? Should I write a subquery?
DISTINCT is almost never needed in a query that uses GROUP BY, so your query doesn't require it. So just use:
SELECT CONCAT('There are a total of ', COUNT(*), ' ', OCCUPATION, 's.')
FROM OCCUPATIONS
GROUP BY OCCUPATION
ORDER BY COUNT(*), OCCUPATION ASC;
Note that SELECT DISTINCT is a single keyword -- like LEFT JOIN or IS NULL. Nothing is supposed to go between the keywords.
I do a sql oj on hackerrank. I need to first order people with name and order occupation with corresponding count. Database table like the png image display table structure.
I want to use
select type from
(
(
SELECT name as type, 1 as filter FROM occupations
order by name
)
UNION All
(
select concat(count(occupation), ' ', lower(occupation), 's.') as type, 2 as filter
FROM occupations
group by occupation
order by count(occupation)
)
) result
order by filter, type
to solve this question, but get "[Err] 1111 - Invalid use of group function".
If I comment order by count(occupation) could be okay. Or just use
select concat(count(occupation), ' ', lower(occupation), 's.') as type, 2 as filter
FROM occupations
group by occupation
order by count(occupation)
is also okay, but once union would receive this error
(
SELECT name as type, 1 as filter FROM occupations
order by name
)
UNION All
(
select concat(count(occupation), ' ', lower(occupation), 's.') as type, 2 as filter
FROM occupations
group by occupation
order by count(occupation)
)
but I copy this union to postgresql(change string contract function) is okay, no this error.postgresql is okay
In mysql, I must to convert this "order by count(occupation)" set to another temporary table to solve this error, like this:
select type from
(
(SELECT concat(name, '(', LEFT(occupation , 1), ')') as type, 1 as filter FROM occupations
order by name)
UNION All
(select * from
(
select concat('There are a total of ', count(occupation), ' ', lower(occupation), 's.') as type, 2 as filter
FROM occupations
group by occupation
order by count(occupation)
)
result)
) last
order by filter, type
I am very confused, very appreciate your help!
order by is invalid within unions. Move the order by outside of the union operation.
This question already has answers here:
How can I order entries in a UNION without ORDER BY?
(7 answers)
Closed 4 years ago.
I have a problem to solve.
I have a table Occupationswith Name and Occupation.
My task is to:
1.Query an alphabetically ordered list of all names in OCCUPATIONS, immediately followed by the first letter of each profession as a parenthetical (i.e.: enclosed in parentheses). For example: AnActorName(A), ADoctorName(D), AProfessorName(P), and ASingerName(S).
query the number of ocurrences of each occupation in OCCUPATIONS. Sort the occurrences in ascending order, and output them in the following format:
There are a total of [occupation_count] [occupation]s.
If more than one Occupation has the same they should be ordered alphabetically.
I am almost done with the query
SELECT TEMP.CON1
FROM (
SELECT NAME, CONCAT(NAME,'(', LEFT(OCCUPATION, 1),')') AS CON1
FROM OCCUPATIONS
ORDER BY NAME
) AS TEMP
UNION
SELECT TEMP2.CON2
FROM (
SELECT COUNT(*) AS NR, CONCAT('THERE ARE A TOTAL OF ', COUNT(OCCUPATION),' ', OCCUPATION, 's') AS CON2
FROM OCCUPATIONS
GROUP BY OCCUPATION
ORDER BY NR, OCCUPATION
) AS TEMP2
but I don't know how to keep the order of the first section after the two sections are united.
If anyone knows the answer I would be superglad for sharing.
SELECT CON
FROM
(
SELECT 1 as SEQ, 0 as NR, NAME ,TEMP.CON1 as CON
FROM (
SELECT NAME, CONCAT(NAME,'(', LEFT(OCCUPATION, 1),')') AS CON1
FROM OCCUPATIONS
ORDER BY NAME -- don't need
) AS TEMP
UNION
SELECT 2, NR, null, TEMP2.CON2
FROM (
SELECT COUNT(*) AS NR, CONCAT('THERE ARE A TOTAL OF ', COUNT(OCCUPATION),' ', OCCUPATION, 's') AS CON2
FROM OCCUPATIONS
GROUP BY OCCUPATION
ORDER BY NR, OCCUPATION -- don't need
) AS TEMP2 ) T
ORDER BY SEQ, NR, NAME, CON
UNION ALL would keep the order, and would work just as well in this case as your result sets are totally different.
The difference between union and union all is that UNION removes duplicates, which causes reordering, where UNION ALL simply adds the next set of results to the end of the existing result set. Since you are manipulating the strings on both selects, there is no real chance of there being duplicates in the results between TEMP and TEMP2. This will also get rid of some of the cost of the query, since UNION is more expensive than UNION ALL, as it needs to check for duplicates.
SELECT TEMP.CON1
FROM (
SELECT NAME, CONCAT(NAME,'(', LEFT(OCCUPATION, 1),')') AS CON1
FROM OCCUPATIONS
ORDER BY NAME
) AS TEMP
UNION ALL
SELECT TEMP2.CON2
FROM (
SELECT COUNT(*) AS NR, CONCAT('THERE ARE A TOTAL OF ', COUNT(OCCUPATION),' ', OCCUPATION, 's') AS CON2
FROM OCCUPATIONS
GROUP BY OCCUPATION
ORDER BY NR, OCCUPATION
) AS TEMP2
This being said, the way I read the instructions, I wouldn't expect both results to be desired in the same result set.
I`m trying to solve this challenge:
https://www.hackerrank.com/challenges/the-pads
My solution is this in MySQL:
(SELECT CONCAT(Name,'(',SUBSTR(Occupation,1,1),')') FROM Occupations ORDER BY Name)
UNION
(SELECT CONCAT('There are total ', COUNT(Occupation), ' ',LOWER(Occupation),'s.') AS total FROM Occupations
GROUP BY Occupation
ORDER BY total);
However it fails to ORDER BY total.
Ashley(P)
Samantha(A)
Julia(D)
Britney(P)
Maria(P)
Meera(P)
Priya(D)
Priyanka(P)
Jennifer(A)
Ketty(A)
Belvet(P)
Naomi(P)
Jane(S)
Jenny(S)
Kristeen(S)
Christeen(S)
Eve(A)
Aamina(D)
There are total 4 actors.
There are total 3 doctors.
There are total 7 professors.
There are total 4 singers.
If I only run
SELECT CONCAT('There are total ', COUNT(Occupation), ' ',LOWER(Occupation),'s.') AS total FROM Occupations
GROUP BY Occupation
ORDER BY total
it does order:
There are total 3 doctors.
There are total 4 actors.
There are total 4 singers.
There are total 7 professors.
The result gets ordered by the final ORDER BY clause. This is ORDER BY total, i.e. by the first column. (You only give this name in the second part of UNION, which would probably not work in another DBMS. You should name the columns you select in a UNION query in the first part.)
You want to get names first, then the aggregates. Then you want names alphabetically, aggregates by count (i.e. not alphabetically, not 1 -> 10 -> 11 -> 2 -> 20 ..., but 1 -> 2 -> 10 -> 11 -> 20 ...) then by job name. You can create sortkeys for this task. I assume you really want UNION ALL, not UNION. If I am wrong, change it :-)
SELECT txt
FROM
(
SELECT
CONCAT(Name, '(', SUBSTR(Occupation, 1, 1), ')') as txt,
1 as sortkey1,
CONCAT(Name, '(', SUBSTR(Occupation, 1, 1), ')') as sortkey2
FROM Occupations
UNION ALL
SELECT
CONCAT('There are total ', COUNT(Occupation), ' ', LOWER(Occupation), 's.') AS txt,
2 + COUNT(Occupation) as sortkey1,
LOWER(Occupation) as sortkey2
FROM Occupations
GROUP BY Occupation
) data
ORDER BY sortkey1, sortkey2;
That is correct. The ordering of the result set is based only on the outermost order by. This is true for union as for other operations.
(SELECT CONCAT(Name,'(', SUBSTR(Occupation,1,1),')') AS total
FROM Occupations
ORDER BY Name
)
UNION ALL
(SELECT CONCAT('There are total ', COUNT(Occupation), ' ', LOWER(Occupation), 's.') AS total
FROM Occupations
GROUP BY Occupation
)
ORDER BY (CASE WHEN total LIKE 'There are total%' THEN 1 ELSE 0 END),
Total;
This assumes that Name never starts with 'There are total', which seems likely.
#gordon answer is fine
But for a more generic case you have to create a "dummy" field to separate each group.
(SELECT CONCAT(Name,'(', SUBSTR(Occupation,1,1),')') as Name,
0 as dummy
FROM Occupations
)
UNION ALL
(SELECT CONCAT('There are total ', COUNT(Occupation), ' ', LOWER(Occupation), 's.') AS Name,
1 as dummy
FROM Occupations
GROUP BY Occupation
)
ORDER BY dummy, name
Based on the answers and my best understanding I came with this solution that works for this case:
(SELECT CONCAT(Name,'(',SUBSTR(Occupation,1,1),')') as total FROM Occupations ORDER BY Name)
UNION ALL
(SELECT CONCAT('There are total ', COUNT(Occupation), ' ',LOWER(Occupation),'s.') AS total FROM Occupations
GROUP BY Occupation)
ORDER BY total;
This worked for me.
you can give two different select queries whith out UNION/ UNION ALL.
SELECT Concat(NAME, '(', Substr(occupation, 1, 1), ')') AS Result
FROM occupations
ORDER BY NAME;
SELECT Concat('There are a total of ', Count(*), ' ', Lower(occupation), 's.')
FROM occupations
GROUP BY occupation
ORDER BY Count(*), occupation;