can anyone please suggest how we can implement a correlated query in hive.
in SQL i am able to write but when i tried the same in hive it giving a error.
SQL query for reference
SELECT M.MODELNAME,(SELECT SALE FROM CAR WHERE MONTH='Jan' AND MODELID=M.MODELID) AS JAN_SALE,(SELECT SALE FROM CAR WHERE MONTH='Feb' AND MODELID=M.MODELID) AS FEB_SALE,(SELECT SALE FROM CAR WHERE MONTH='Mar' AND MODELID=M.MODELID) AS MAR_SALE FROM MODEL M INNER JOIN CAR C ON(C.MODELID=M.MODELID);
Please suggest.
thanks in advance :)
SELECT M.MODELID,
M.MODELNAME,
C.MONTH,
SUM(C.SALE) as SUM_SALE
FROM MODEL M INNER
JOIN CAR C ON C.MODELID=M.MODELID
GROUP By M.MODELID, M.MODELNAME, C.MONTH
thanks Kim
but what i exactly want is in below format
MODELNAME | JAN_SALE | FEB_SALE | MAR_SALE
your query is giving 9 rows in output but my requirement is a single line for each model
i tried to write a query for the same, please review n suggest if it is good to be used or will it cause any performance issues?
hive> select distinct m.modelname,e.sale jan_sale,e2.sale feb_sale,e3.sale mar_sale from (select * from car where month='JAN') e join car c on(e.modeid=c.modeid) join (select * from car where month='FEB') e2 on(c.modeid=e2.modeid) join (select * from car where month='MAR') e3 on (c.modeid=e3.modeid) join model m on (c.modeid=m.modelid);
result is :
Audi 20.0 21.0 30.0
Duster 20.0 21.0 30.0
Maruti 12.0 13.0 16.0
Related
I'm trying to join two tables in postgresql with the following structure, which is the relation between some areas and some points surrounding it
Table 1 "d_hid_t"
id_rank | dem_hid_m3s
1 3.6
2 3.45
3 3.40
4 2.35
5 2.33
Table 2 "disph"
id_rank | disph_m3s
1 0.058
1 1.36
1 1833.4
2 0.017
2 208.69
3 0.39
3 40.79
... ...
I'm expecting to get the join output based on the maximum value found for the unique ID of table 1, without repeating the other related values, for example
Table 3 "output"
id_rank | disph_m3s
1 1833.4
2 208.69
3 40.69
... ...
So far I followed some instruction on this stack overflow post Select first record in a One-to-Many relation using left join but with no success. I keep getting the error "aggregate functions are not allowed in JOIN conditions".
Right now my code looks like this:
SELECT a.id_rank, a.dem_hid_m3s, a.geom, b.id_disp, b.dist_km, b.disph_m3s
FROM d_hid_t as a
LEFT JOIN disph as b
ON a.id_rank = b.id_rank
AND (SELECT max(b.disph_m3s) WHERE a.dem_hid_m3s <= b.disph_m3s)
A pretty simply method uses distinct on. I might use it before joining:
SELECT h.*, d.*
FROM d_hid_t h LEFT JOIN
(SELECT DISTINCT ON (d.id_rank) d.*
FROM disph d
ORDER BY d.id_rank, disph_m3s DESC
) d
USING (id_rank);
Note the use of meaningful table aliases rather than arbitrary letters.
I'm working through some problems and I can't seem to get the expected results for this one. The question is below with what is in my code right now and also the expected results. If anyone help that would be great. I'm just trying to get a understanding on this and can't seem to get my head around what exactly this is asking as you can see my code I have now isn't close to what the expected result is as of right now. Also I added the schema this will show whats in what table if needed for your guys help.
Question:
List the course number of courses wherein students have received grades for every one of the possible defined grade types. Order by course number.
My code so far:
SELECT g.Student_id, g.Grade_type_code
FROM Grade g LEFT OUTER JOIN Section s
ON g.Section_id = s.Section_id
GROUP BY g.Student_id, g.Grade_type_code
ORDER BY g.Student_id;
Any help would be great, also here is the Schema.
DBMS: I'm using Oracle SQL Developer
Here is the Expected Result
COURSE_NO
----------
20
25
100
120
122
125
130
135
Note: The Chapter for this problem is based off using
LEFT OUTER JOIN
My Current results
STUDENT_ID GRADE_TYPE_CODE
---------- ---------------
102 FI
102 HM
102 MT
102 PA
102 QZ
103 FI
103 HM
103 MT
103 PA
103 QZ
104 FI
104 HM
Based on your ER diagram I believe this query should return a list of courses whose enrolled students have collectively received all of the grade types listed in the GRADE_TYPE table.
select s.course_no,
c.descr,
count(distinct g.grade_type_code) as num_grade_types
from grade g
join enrollment e
on g.student_id = e.student_id
and g.section_id = e.section_id
join section s
on e.section_id = s.section_id
join course c
on s.course_no = c.course_no
group by s.course_no, c.descr
having count(distinct g.grade_type_code) = (select count(grade_type_code)
from grade_type)
I didn't notice your expected result was only the course # (you can just get rid of the columns you don't want from the select list). Also the join to the COURSE table is only there to get the course description, so if you don't want the course description selected, you do not need that join.
You need to select COURSE_NO instead. And also use JOIN and not LEFT JOUTER JOIN.
Something like this:
select COURSE_NO from
(
SELECT distinct (s.COURSE_NO)
FROM Grade g JOIN Section s
ON g.Section_id = s.Section_id
)
ORDER BY s.COURSE_NO;
Currently, I have 2 tables with the following data:
[CAR]
Honda
Ford
Mazda
[FEATURE]
CD player
Sunroof
Leather
In another table, I store their relationships.
[CAR_FEATURE]
Honda | CD Player
Mazda | CD Player
Mazda | Sunroof
Mazda | Leather
My problem is... I need to select the [CAR] that has all the [FEATURE] I am looking for -- all or nothing.
For example, if I am looking for a car with a CD Player, Sunroof, AND Leather, then it would output Mazda.
If I am looking for a car with a CD Player, then it would ONLY output Honda.
If I am looking for a car with a Sunroof, then it would output nothing because I am searching for all or nothing.
How would I write the query statement in SQL for this particular case?
This variation of T McKeown's query will get you a car matching all the features exactly, not more or less:
SELECT CAR
FROM CAR_FEATURE
GROUP BY CAR
HAVING SUM(CASE WHEN FEATURE IN ('CD Player', 'Sunroof', 'Leather')
THEN 1
ELSE -1
END) = 3
This would work:
SELECT CAR
FROM CAR_FEATURE
WHERE FEATURE IN ('CD Player', 'Sunroof', 'Leather')
GROUP BY CAR
HAVING COUNT(*) = 3
Just adjust the HAVING clause based on the features, you could pass in a CSV list of features and create a TABLE variable table that has all the features so the query could be like this:
DECLARE #LIST_OF_FEATURES TABLE(FEATURE VARCHAR(50))
--INSERT INTO THE #LIST_OF_FEATURES USING THE FORXML
SELECT CAR
FROM CAR_FEATURE
WHERE FEATURE IN (SELECT FEATURE FROM #LIST_OF_FEATURES)
GROUP BY CAR
HAVING COUNT(*) = (SELECT COUNT(*) FROM #LIST_OF_FEATURES)
I don't know the exact table structure, so I will improvise with field names. I hope it's clear from context:
SELECT c.*
FROM CAR c
JOIN CAR_FEATURE cf ON (c.id = cf.car_id)
JOIN FEATURE f ON (f.id = cf.feature_id)
LEFT JOIN FEATURE f2 ON (f2.id = cf.feature_id
AND f2.id NOT IN (<list of feature ids>))
WHERE f.id IN (<same list of features ids as above>)
AND f2.id IS NULL
This would bring the cars that have the features you want, but that do not have any other features.
Concrete example. Suppose your feature id are the names (not a great idea, but good for the example), then you would write:
SELECT c.*
FROM CAR c
JOIN CAR_FEATURE cf ON (c.id = cf.car_id)
JOIN FEATURE f ON (f.id = cf.feature_id)
LEFT JOIN FEATURE f2 ON (f2.id = cf.feature_id
AND f2.id NOT IN ('CD Player','Sunroof'))
WHERE f.id IN ('CD Player','Sunroof')
AND f2.id IS NULL
Hope this helps!
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I been unable to figure out a way to do the query below without using a parameter. The database has over 2000 possible values for the parameter, so what I want is to output a table that lists all the parameters in one column, and the output from the query in the other. Below is a simplified version of what works now:
SELECT [enter name] AS ExclName,
Sum(revenue) AS MaxRev
FROM tbltasks
WHERE tbltasks.task IN (SELECT DISTINCT tblabilities.task
FROM tblabilities
WHERE tblabilities.name <> [enter name]);
tbltasks tblpeople tblabilities
task revenue name name task
A 10 Bob Bob A
B 9 Tom Tom A
C 8 Jack Jack A
D 7 Mary Tom B
E 6 Diane Jack B
F 5 Alice Mary B
G 4 Sam Jack C
H 3 Mary C
I 2 Diane C
Mary D
Diane D
Alice D
Diane E
Alice E
Sam E
Bob F
Tom G
Alice H
Right now I run the query, manually enter a name like "Bob" when prompted, and get a single row of output like:
ExclName MaxRev
Bob 47
But what I want is the complete table:
ExclName MaxRev
Bob 47
Tom 48
Jack 52
Mary 52
Diane 52
Alice 49
Sam 52
Or in other words, I want to know what maximum revenue could be achieved by a team that excluded the named member. The real application is more complicated, as there are other groupings involved (eg. if exclude Jack, must also exclude Mary), but I think if I solve the simple problem above I can handle the rest.
I keep thinking there must be a way to use the names from tblPeople and link them to the MaxRev calculation with a single query, but I haven't been able to figure it out. I could do some code to loop through all the parameters, but am hoping there is a more straightforward solution. Appreciate anyone's input.
you can simply extend your query for all people:
select
p.name as ExclName,
sum(t.revenue) as MaxRev
from tblpeople as p
cross join tbltasks as t
where
t.task in
(
select l.task
from tblabilities as l
where l.name <> p.name
)
group by p.name
sql fiddle demo
update. Still don't know which RDBMS do you using, here's SQL Server solution, it's possible to split solution below into temp table, variable and query to improve performance, but it should be faster than first one anyway (if you have appropriate indexes on your table):
with cte as (
select l.[name], sum(t.[revenue]) as [revenue]
from tblabilities as l
inner join tbltasks as t on t.[task] = l.[task]
where
not exists
(
select *
from tblabilities as tl
where tl.[task] = l.[task] and tl.[name] <> l.[name]
)
group by l.[name]
)
select
p.[name] as ExclName,
t.revenue_total - isnull(c.[revenue], 0) as MaxRev
from tblpeople as p
left outer join cte as c on c.[name] = p.[name]
outer apply (
select sum(tt.[revenue]) as revenue_total
from tbltasks as tt
where
tt.[task] in (select tl.[task] from tblabilities as tl)
) as t
order by p.[name]
sql fiddle demo
Table 1
csstatus
csid status
122 defaulter
123 regular
124 registery
125 defaulter
table 2
csplotdetials
csid plotsize
122 50
123 25
124 30
125 25
qunery result
Status totalplotsize
defaulter 75
regular 25
....
how i can do that both tables are not in relationship they are in realtionship with another table
SELECT status, sum(plotsize) as totalplotsize
FROM csstatus cs
INNER JOIN csplotdetials cp ON cs.csid = cp.csid
GROUP BY status
I'm assuming that tables are linked via csID coluymn from both tables.
SELECT a.csID, a.status, SUM(b.plotsize) totalPlotSize
FROM ccstatus a
INNER JOIN csplotdetails b
On a.csID = b.csID
GROUP BY a.csID, a.status
SQLFiddle Demo
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
I must be missing something here, because it looks like I can infer a relationship between the two tables (on the csid column) to produce the results you are after:
SELECT csstatus.status AS Status, SUM(csplotdetials.plotsize) AS totalplotsize
FROM csplotdetials
INNER JOIN csstatus ON csplotdetials.csid = csstatus.csid
GROUP BY csstatus.status
SQL Fiddle example