How to create group by function for multiple columns? - sql-server-2008

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)?

Related

MySQL Multiple Columns Sum() in different / multiple rows

I have basic table looking like:
When I am using the Query:
SELECT *, SUM(cr) AS cr, SUM(dr) AS dr FROM my_table GROUP BY id
I am getting:
and that's correct!
What's the proper query to get (each sum in different row):
I already tried GROUP BY ID,CR,DR and GROUP BY CR,DR,ID but with not the results that I wanted. (I don't care if the 0 values are also NULL)
You can do:
select id, sum(dr) as dr, 0 as cr from my_table group by id
union all
select id, 0, sum(cr) from my_table group by id
order by id, dr desc

Need list of data using DISTINCT, COUNT, MAX

The table structure is as below,
My first SQL query is as below,
SELECT DISTINCT(IndustryVertical)
, COUNT(IndustryVertical) AS IndustryVerticalCount
, City
FROM `records`
WHERE City!=''
GROUP
BY IndustryVertical
, City
ORDER
BY `IndustryVerticalCount` DESC
by running the above query I'm getting the below,
What I'm trying to achieve is to get the List of all the DISTINCT CITY with ONLY ONE MAX(IndustryVerticalCount) and IndustryVertical.
Tried several things with no hope.
Anyone, please guide me.
There're several records in each City values. what I'm trying to achieve is that getting,
All the distinct City Values
The MAX COUNT of industryVertical
Name of industryVertical
The record I'm getting is as below,
What I'm trying to get,
The above record is reference purpose. Here, you can see only distinct city values with only one the vertical name having max count.
Since you are using group by, it will automatically select only distinct rows. Since you are using group by on two columns, you will get rows in which only combination of both columns is distinct.
What you now have to do is use this resulting table, and perform a query on it to find the maximum count grouped by city.
SELECT IndustryVertical, IndustryVerticalCount, City from
( SELECT IndustryVertical
, COUNT(IndustryVertical) AS IndustryVerticalCount
, City
FROM `records`
WHERE City!=''
GROUP
BY IndustryVertical
, City) as tbl where IndustryVerticalCount IN (Select max(IndustryVerticalCount) from ( SELECT IndustryVertical
, COUNT(IndustryVertical) AS IndustryVerticalCount
, City
FROM `records`
WHERE City!=''
GROUP
BY IndustryVertical
, City) as tbl2 where tbl.City=tbl2.city)
This may not be the most efficient method, but I think it will work.
How about this? I think it should be worked:
DECLARE #DataSet TABLE (
City VARCHAR(50),
IndustryVertical VARCHAR(50),
IndustryVerticalCount INT
)
INSERT INTO #DataSet SELECT 'Bangalore', 'Consumer Internet', 279
INSERT INTO #DataSet SELECT 'Bangalore', 'Technology', 269
INSERT INTO #DataSet SELECT 'Bangalore', 'Logistics', 179
INSERT INTO #DataSet SELECT 'Mumbai', 'Technology', 194
INSERT INTO #DataSet SELECT 'Mumbai', 'Consumer Internet', 89
SELECT
table_a.*
FROM #DataSet table_a
LEFT JOIN #DataSet table_b
ON table_a.City = table_b.City
AND table_a.IndustryVerticalCount < table_b.IndustryVerticalCount
WHERE table_b.IndustryVerticalCount IS NULL
I think you simply want a HAVING clause:
SELECT r.IndustryVertical,
COUNT(*) AS IndustryVerticalCount,
r.City
FROM records r
WHERE r.City <> ''
GROUP BY r.IndustryVertical, r.City
HAVING COUNT(*) = (SELECT COUNT(*)
FROM records r2
WHERE r2.City = r.City
ORDER BY COUNT(*) DESC
LIMIT 1
)
ORDER BY IndustryVerticalCount DESC;

How to create group by function for firstname,mark1,mark2,mark3?

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.

I want to merge two tables [Tabl1] and [Tabl2] and show result by ID where [Tabl1].[names] = 'any string name'?

In my example where name like '' show all value tabl2 with tabl1
SELECT *
FROM
(SELECT
ID, names, NULL AS address, work, note
FROM
Tabl1
UNION
SELECT
ID, name, address, NULL, NULL
FROM
Tabl2) as x
ORDER BY
id, note DESC, address
With CTE_NAME(ID, names) --Column names for Temporary table
AS
(
SELECT ID , NAME FROM TABLE1
UNION
SELECT ID , NAME FROM TABLE2
)
SELECT * FROM CTE_NAME --SELECT or USE CTE temporary Table
WHERE name = "x"
ORDER BY ID
You'll need to use UNION to combine the results of two queries. In your case:
SELECT ID, names, NULL AS address, work, note
FROM Tabl1
GROUP BY names
UNION ALL
SELECT ID, name, address, NULL, NULL
FROM Tabl2
GROUP BY Tabl3
Note - If you use UNION ALL as in above, it's no slower than running the two queries separately as it does no duplicate-checking.

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