How to create group by function for firstname,mark1,mark2,mark3? - sql-server-2008

I have merged three tables using union query and created group by for id already.
Here is my code:
select Id,
Max(Firstname) Firstname,
Max(Mark1) Mark1,
Max(Mark2) Mark2,
Max(Mark3) Mark3
from
(
select Id,Firstname,Null as Mark1,Null as Mark2,Null as Mark3 from Parent
union
select Id,Null as Firstname,Mark1,Mark2,Null as Mark3 from Child
union
select Id,Null as Firstname,Null as Mark1,Null as Mark2,Mark3 from Mark
) t
group by Id
What my question is will i able to create group by function for rest of the columns without using join query?
Thanks in advance.

Related

Get records as per the given ids' mysql

This is the query i am executing
SELECT email,firstname,lastname FROM `sco_customer`
WHERE id_customer IN (7693,7693,7693,7693,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,7693,3,3,3,3,3,7693,7693,3,3,3,7693,3,3,3)
This gives me only two records as their are same number of id_customer is filtered i.e 7693,3
email firstname lastname
abc#any.com Test Mage
abc2#any.com User Mage
It should give the same number of records as much is the id_customer
Any thoughts how this can be achieved ?
Try below. Instead of WHERE clause you can generate a dummy table and join it with your main table.(WITH works for version 8 or above)
WITH SAMPLE AS
(
SELECT 7693 AS ID FROM DUAL
UNION ALL
SELECT 3 AS ID FROM DUAL
)
SELECT email,firstname,lastname FROM `sco_customer`
INNER JOIN SAMPLE ON SAMPLE.ID=ID_CUSTOMER
Below mysql version 8:
SELECT email,firstname,lastname FROM `sco_customer`
INNER JOIN (
SELECT 7693 AS ID FROM DUAL
UNION ALL
SELECT 3 AS ID FROM DUAL
)SAMPLE ON SAMPLE.ID=ID_CUSTOMER
The following statement should solve you problem:
SELECT email,firstname,lastname FROM `sco_customer`
join (select 7693 as id_customer union all
select 7693 union all
select 7693 union all
select 3 union all
select 3 union all
select 3
) tmp on sco_customer.id_customer = tmp.id_customer

How to create group by function for multiple columns?

How to create group by function for multiple columns?
Here I'm using this query.By using Max aggregate function,I removed all the null values and got the result.
select Id,
MAX(Firstname) Firstname,
MAX(Mark1) Mark1,
MAX(Mark2) Mark2,
MAX(Mark3) Mark3
from
(
select Id,Firstname,Null as Mark1,Null as Mark2,Null as Mark3 from Parent
union
select Id,Null as Firstname,Mark1,Mark2,Null as Mark3 from Child
union
select Id,Null as Firstname,Null as Mark1,Null as Mark2,Mark3 from Mark
) t
group by Id
So what my question is,will i able to create group by for rest of the fieldnames(firstname,mark1,mark2,mark3)?

SQL - Trouble using COUNT query

Good day again to all SQL guru here :)
I have a problem querying my table using COUNT.
This is the data inside of the table (tblstudentoffense)
And this is the RESULT that I want (Let's say that there is a new column after the offenseType that will count the Stealing and Gaming Offense
Is this possible? If possible kindly add an explanation with your provided code. Thanks :)
Using subquery to get count and concatenate count with main select statement
SELECT DISTINCT OffenseType + ' ' + CAST(B.Cnt AS VARCHAR) ,
Othercolumn1,Othercolumn2
FROM Your_tableName A
JOIN
(
SELECT COUNT(*) Cnt , StudentId
FROM Your_tableName
GROUP BY StudentId
) B ON B.StudentId = A.StudentId
Try using CONCAT_WS().The CONCAT_WS() function is used to join two or more strings with a separator.
Note: offensetypeCount is an new column having expected output.
SELECT *,CONCAT_WS(' ',offensetype,count(offenseType) AS offensetypeCount FROM tblstudentoffense GROUP BY offensetype;
Is this what you are looking for:
WITH SRC AS
(SELECT 'STEALING' OFFENSETYPE,'1' STUDENTID FROM DUAL UNION ALL
SELECT 'STEALING' OFFENSETYPE,'1' STUDENTID FROM DUAL UNION ALL
SELECT 'STEALING' OFFENSETYPE,'1' STUDENTID FROM DUAL UNION ALL
SELECT 'STEALING' OFFENSETYPE,'1' STUDENTID FROM DUAL UNION ALL
SELECT 'GAMING' OFFENSETYPE,'1' STUDENTID FROM DUAL UNION ALL)
SELECT OFFENSETYPE,STUDENTID,COUNT(*) FROM SRC GROUP BY OFFENSETYPE,STUDENTID;
You could try
SELECT CONCAT(offensetype, ' ', COUNT(offensetype)) AS offenseType,
studentid,
offenseln,
offensefn,
offensemn,
offensesuffixname
FROM tblstudentoffense
GROUP BY offensetype,
studentid,
offenseln,
offensefn,
offensemn,
offensesuffixname;
I've created a sample at this link http://rextester.com/WZGW41761.

mysql - Get two greatest values from multiple columns

We can use GREATEST to get greatest value from multiple columns like below
SELECT GREATEST(mark1,mark2,mark3,mark4,mark5) AS best_mark FROM marks
But now I want to get two best marks from all(5) marks.
Can I do this on mysql query?
Table structure (I know it is wrong - created by someone):
student_id | Name | mark1 | mark2 | mark3 | mark4 | mark5
This is not the most elegant solution but if you cannot alter the table structure then you can unpivot the data and then apply a user defined variable to get a row number for each student_id. The code will be similar to the following:
select student_id, name, col, data
from
(
SELECT student_id, name, col,
data,
#rn:=case when student_id = #prev then #rn else 0 end +1 rn,
#prev:=student_id
FROM
(
SELECT student_id, name, col,
#rn,
#prev,
CASE s.col
WHEN 'mark1' THEN mark1
WHEN 'mark2' THEN mark2
WHEN 'mark3' THEN mark3
WHEN 'mark4' THEN mark4
WHEN 'mark5' THEN mark5
END AS DATA
FROM marks
CROSS JOIN
(
SELECT 'mark1' AS col UNION ALL
SELECT 'mark2' UNION ALL
SELECT 'mark3' UNION ALL
SELECT 'mark4' UNION ALL
SELECT 'mark5'
) s
cross join (select #rn := 0, #prev:=0) c
) s
order by student_id, data desc
) d
where rn <= 2
order by student_id, data desc;
See SQL Fiddle with Demo. This will return the top 2 marks per student_id. The inner subquery is performing a similar function as using a UNION ALL to unpivot but you are not querying against the table multiple times to get the result.
I think you should change your database structure, because having that many marks horizontally (i.e. as fields/columns) already means you're doing something wrong.
Instead put all your marks in a separate table where you create a many to many relationship and then perform the necessary SELECT together with LIMIT.
Suggestions:
Create a table that you call mark_types. Columns: id, mark_type. I
see that you currently have 5 type of marks; it would be very simple
to add additional types.
Change your marks table to hold 3 columns: id,
mark/grade/value, mark_type (this column foreign constraints to
mark_types).
Write your SELECT query with the help of joins, and GROUP BY mark_type.
you can create a temporary table and then
Create a temporary table in a SELECT statement without a separate CREATE TABLE
query that table as follows
SELECT TOP 2 * FROM temp
ORDER BY mark DESC
then
drop temp table
Okay here's a new answer that's should work with the current table structure:
SELECT `student_id`, `Name`, `mark` FROM (SELECT `student_id`, `Name`, `mark1` AS `mark` FROM `marks`
UNION ALL
SELECT `student_id`, `Name`, `mark2` AS `mark` FROM `marks`
UNION ALL
SELECT `student_id`, `Name`, `mark3` AS `mark` FROM `marks`
UNION ALL
SELECT `student_id`, `Name`, `mark4` AS `mark` FROM `marks`
UNION ALL
SELECT `student_id`, `Name`, `mark5` AS `mark` FROM `marks`) AS `marks`
ORDER BY `mark` DESC
LIMIT 2

Selecting the frequency of a result that could appear in multiple columns (SQL)

I have a table with a list of names spread across five different columns. I'm trying to get the 6 most frequent distinct names. Each name will only appear in each record once. The five columns are name_1, name_2...name_5. And just for names sake call the table 'mytable'.
Any help would be much appreciated.
Here's one approach:
SELECT name, COUNT(1)
FROM ( SELECT name_1 AS name FROM mytable
UNION ALL SELECT name_2 AS name FROM mytable
UNION ALL SELECT name_3 AS name FROM mytable
UNION ALL SELECT name_4 AS name FROM mytable
UNION ALL SELECT name_5 AS name FROM mytable
) AS myunion
GROUP BY name
ORDER BY COUNT(1) DESC LIMIT 6
;
How many rows are there in the table?
try this:
SELECT iTable.iName, Count(iTable.iName) as TotalCount
FROM
(
SELECT DISTINCT name_1 as iName FROM myTable
UNION
SELECT DISTINCT name_2 as iName FROM myTable
UNION
SELECT DISTINCT name_3 as iName FROM myTable
UNION
SELECT DISTINCT name_4 as iName FROM myTable
UNION
SELECT DISTINCT name_5 as iName FROM myTable
) as iTable
GROUP BY iTable.iName
ORDER BY TotalCount DESC
LIMIT 6
You should be able to select all the names from each table and union the results together. Then you can count the number of times each name occurs.
select *
from
(
select name, count(*)
from (
select name from table1
union all
select name from table2
union all
select name from table3
union all
select name from table4
union all
select name from table5
)
group by name
order by count(*) desc
)
where rownum <= 6
UNION + subselect should work for you in this case.
SELECT name_1, COUNT(*) FROM (
SELECT name_1 FROM mytable
UNION ALL SELECT name_2 FROM mytable
UNION ALL SELECT name_3 FROM mytable
UNION ALL SELECT name_4 FROM mytable
UNION ALL SELECT name_5 FROM mytable
) AS names GROUP BY name_1 ORDER BY 2 DESC LIMIT 6;