I have a question.
Here is the story, I have Student mark sheet (Table A)
Name Course Marks
Student 01 32472 44
Student 02 32472 80
Student 03 32472 67
Student 04 32472 76
Student 05 32472 56
Student 06 32472 98
Student 07 32472 13
Student 08 32472 68
Student 09 32472 84
Student 10 32472 93
And I have sheet (Table B ) for cut off marks for medals.
Medel Course CutOff
Silver 32472 0-69
Gold 32472 70 -84
Platinum 32472 85 -100
Could you please help me to get following sheet (Table) in SQL.
Name Course Medal
Student 01 32472 Silver
Student 02 32472 Gold
Student 03 32472 Silver
Student 04 32472 Gold
Student 05 32472 Silver
Student 06 32472 Platinum
Student 07 32472 Silver
Student 08 32472 Silver
Student 09 32472 Gold
Student 10 32472 Platinum
How Can I join Table A (Student marks sheet) and Table B (Medal cut off marks sheet) then get Final Table ?
Really appreciate your answers/comments.
Thank you
Gayan
After your edit:
;WITH CteMedals AS(
SELECT *,
rStart = LEFT(CutOff, CHARINDEX('-', CutOff) - 1),
rEnd = SUBSTRING(CutOff, CHARINDEX('-', CutOff) + 1, LEN(CutOff) - CHARINDEX('-', CutOff))
FROM TableB
)
SELECT
a.Name, a.Course, ISNULL(b.Medal, 'Silver') AS Medal
FROM TableA a
OUTER APPLY(
SELECT TOP 1 Medal
FROM CteMedals
WHERE
a.Marks BETWEEN rStart AND rEnd
ORDER BY rEnd DESC
)b
You can use OUTER APPLY:
SELECT
a.Name, a.Course, ISNULL(b.Medal, 'Silver') AS Medal
FROM TableA a
OUTER APPLY(
SELECT TOP 1 Medal
FROM TableB
WHERE
a.Marks >= CutOff
ORDER BY CutOff DESC
)b
Related
Assuming I have a table containing the following information:
ID NAME Boss Main responsibility
01 Tommy x3 Yes
02 Elis x2 Yes
02 Elis x3 No
03 John x65 yes
04 Lille x50 yes
is there a way I can perform a select on the table to get the following(sql :DB2)
ID NAME main responsibility
01 Tommy X3
02 Elis X2(main responsibility) AND X3
03 John X65
04 Lille x50
Thanks
If your version of DB2 support it, you may aggregate and use the LISTAGG() function:
SELECT
ID,
NAME,
LISTAGG(CONCAT(Boss, CASE WHEN main = 'Yes' THEN ' (main)' ELSE '' END), ', ')
WITHIN GROUP(ORDER BY main DESC) AS main
FROM yourTable
GROUP BY ID, NAME
ORDER BY ID;
table 1:
name
rollno
marks
mark
01
25
ram
02
30
june
03
45
table 2:
emp.id
emp.name
emp.sal
01
raj
20000
02
ram
25000
03
pie
30000
table 3:
pro.id
pro.name
pro.price
01
dove
40
02
colgate
60
03
lays
50
how do i query this in athena..?
my athena query:
> create view table4
> as
> select sum(marks) as sumvalues
> from table1
> union
> select sum(emp.sal) as sumvalues
> from table 2
> union
> select sum(pro.price) as sumvalues
> from table 3;
im getting output:
id | sumvalues
01 |100
02 |75000
03 |150
i need table name or any field name in place of id like
table 4:
name
sumvalues
marks
100
emp.sal
75000
pro.price
150
This is going to be a bit convoluted but I have a table named dbo.sizeclassreport. I apologize if this is a bit vague.
It has 78656 rows/records which is not all that immense. There are three salient fields; employment, area, and sizeclass. Sample data below
Area Employment sizeclass
000003 4 01
000001 6 02
000013 12 03
000003 2 01
000005 23 04
000001 7 02
000003 11 03
From here, the result would look this. There are 9 sizeclasses and 18 areas. Need to produce 9 breakdowns of each area. Each area would have a breakdown by size class.
Area Sizeclass Employment in Size Class Number of Sites
Total 00 17(6+11) 3
000003 01 6 (4+2) 2
000003 02 NULL or Empty NULL or Empty
000003 03 11 1
......
000003 09 NULL or Empty NULL or Empty
SELECT
[Areas].[Area],
[classSizes].[sizeclass],
SUM([data].[Employment]) AS [Employment in Size Class],
/*this would be better with your PK */
CASE COUNT([data].[Employment])
WHEN 0 THEN NULL
ELSE COUNT([data].[Employment])
END AS [Number of Sites]
/*These rows create your base matix*/
FROM (SELECT DISTINCT
[Area]
FROM [sizeclassreport]) AS [Areas]
CROSS JOIN (SELECT DISTINCT
[sizeclass]
FROM [sizeclassreport]) AS [classSizes]
/* this is where you select your data*/
LEFT OUTER JOIN [sizeclassreport] [data]
ON [Areas].[Area] = [data].[Area]
AND [classSizes].[sizeclass] = [data].[sizeclass]
GROUP BY
[areas].[Area],
[classSizes].[sizeclass]
ORDER BY
[areas].[Area],
[classSizes].[sizeclass]
It looks like you want all areas and sizeclasss in the output. If so, use cross join to generate the results, then left join and group by for the calculations:
select a.area, sc.sizeclass,
sum(scr.employment) as employment,
count(scr.area) as number_of_sizes
from (select distinct area from dbo.sizeclassreport scr) a cross join
(select distinct sizeclass from dbo.sizeclassreport scr) sc left join
dbo.sizeclassreport scr
on a.area = scr.area and sc.sizeclass = scr.sizeclass
group by a.area, sc.sizeclass;
Note: This returns 0 instead of NULL for the last column. This makes more sense to me. However, you could use NULLIF() if you really want a NULL value.
I have the following data in TABLE_A, where ORG_1 is the parent of ORG_2:
ORG_1 ORG_2
01 02
02 03
02 04
05 06
So, org 01 is the parent of org 02, and org 02 is the parent of 03 and 04. Org 5 is the parent of only org 06.
I need to have unique names/numbers for the chains, and get reported the highest parent in the chain. Chain I define as 'all organisations that are related to each other'.
This is the desired result:
Chain ORG_1 ORG_2 Highest_Parent_In_Chain
1 01 02 01
1 02 03 01
1 02 04 01
2 05 06 05
Chain=1 has a tree structure starting from ORG_1=01. Chain=2 has it's own chain.
I found some info about CONNECT BY, CONNECT BY PRIOR and CONNECT_BY_ROOT, but I don't get it working. Does anyone has an idea how to achieve this with a query in Oracle?
The chain number can be created with the analytic DENSE_RANK() function.
The highest parent in chain is a feature of hierarchical queries: the function CONNECT_BY_ROOT().
Your hierarchical table is non-standard - in a standard arrangement, the top levels (organizations 01 and 05) would also have a row where they appear as ORG_2, with NULL as ORG_1. That way the highest levels in the hierarchy are very easy to find: just look for ORG_1 IS NULL. As it is, the START WITH clause is more complicated, because we must find the tops first. For that we look for values of ORG_1 that do not also appear in ORG_2. That is the work done in the subquery in the START WITH clause.
with
table_a ( org_1, org_2 ) as (
select '01', '02' from dual union all
select '02', '03' from dual union all
select '02', '04' from dual union all
select '05', '06' from dual
)
-- End of simulated input data (for testing purposes only).
-- Solution (SQL query) begins BELOW THIS LINE.
select dense_rank() over (order by connect_by_root(org_1)) as chain,
org_1, org_2,
connect_by_root(org_1) as highest_parent_in_chain
from table_a
connect by org_1 = prior org_2
start with org_1 in
( select org_1 from table_a a
where not exists (select * from table_a where org_2 = a.org_1)
)
;
CHAIN ORG_1 ORG_2 HIGHEST_PARENT_IN_CHAIN
----- ----- ----- -----------------------
1 01 02 01
1 02 03 01
1 02 04 01
2 05 06 05
I have a table "Employees":
E_ID E_Name E_Salary Grade
01 Hansen, Ola 15,000 HC_1
02 Svendson, Tove 15,000 HC_2
03 Svendson, Stephen 32,000 HC_9
04 Pettersen, Kari 21,000 HC_1
05 Sachin, Tendulkar 21,000 HC_2
06 Brian, Lara 19,000 HC_3
I need to return the Employees Salary that have both HC_1 and HC_2 grades. Can someone help me forming the query for this.
Thank you for your time.
I think you want ...
Select e_salary
from employees
where grade in ('HC_1','HC_2')
group by e_salary
having count(distinct grade) = 2