Table A
+----+-------+--------------+-------+----------+
| Id | EName | Company Code | State | City |
+----+-------+--------------+-------+----------+
| 1 | Tom | 110 | NC | Ashville |
| 2 | Dick | | | |
| 3 | Harry | | | |
| 4 | Tonny | 667 | MN | St.pauls |
+----+-------+--------------+-------+----------+
Table B
+----+-------+--------------+-------+----------+
| Id | EName | Company Code | State | City |
+----+-------+--------------+-------+----------+
| 1 | Tom | 110 | NC | Ashville |
| 2 | Dick | 111 | MN | Minesota |
| 3 | Harry | 112 | CA | Oregon |
+----+-------+--------------+-------+----------+
O/p
+----+-------+--------------+-------+----------+
| Id | EName | Company Code | State | City |
+----+-------+--------------+-------+----------+
| 1 | Tom | 110 | NC | Ashville |
| 2 | Dick | 111 | MN | Minesota |
| 3 | Harry | 112 | CA | Oregon |
| 4 | Tonny | 667 | MN | St.pauls |
+----+-------+--------------+-------+----------+
Query:
SELECT Ename,
COALESCE(A.ID, B.ID) AS ID
FROM `Table A` AS A,
`Table B` AS B
WHERE A.`id_column_1`=B.`id_column_1`
UNION ALL
SELECT `Ename,`ID`
FROM `Table B`
WHERE `Id` IS NOT NULL
because I want to pick ID from Table B only for records where it doesn’t exist in Table A.Please tell me whats wrong in my query. Thank you.
I think you want to pull the missing information in a from b. If so:
select a.id,
coalesce(a.name, b.name) as name,
coalesce(a.company, b.company) as company,
coalesce(a.state, b.state) as state,
coalesce(a.city, b.city) as city
from a left join
b
on a.id = b.id;
Related
I have an SQL table with roughly the following structure:
Employee| date | department | Country | Designation
What I would like is to get results with the following structure:
count_emp_per_department | count_emp_per_country | count_emp_per_designation |
Currently I am using UNION ALL, that is constructing a query similar to that one:
SELECT emp_ID, NULL, count(1)
FROM employee
GROUP BY country
UNION ALL
SELECT NULL, emp_ID, count(1)
FROM film
GROUP BY designation
Is this the most effective way to perform multiple aggregations and return all of them in a single result set in Hive?
Kindly share if you new approach which can optimize/enhance performance.
Not sure whether its a real requirement.. as the output isnt that useful.. anyway
Here is the structure and query.
+-----------+------------+----------+
| col_name | data_type | comment |
+-----------+------------+----------+
| emp | int | |
| dt | date | |
| dept | string | |
| country | string | |
| desig | string | |
+-----------+------------+----------+
+--------+-------------+---------+------------+----------+
| t.emp | t.dt | t.dept | t.country | t.desig |
+--------+-------------+---------+------------+----------+
| 1 | 2020-02-02 | human | usa | hr |
| 2 | 2020-02-02 | dir | usa | hr |
| 3 | 2020-02-02 | dir | canada | it |
+--------+-------------+---------+------------+----------+
with q1 as (select dept,count(*) as deptcount from t group by dept),
q2 as (select country,count(*) as countrycount from t group by country),
q3 as (select desig,count(*) as desigcount from t group by desig)
select * from q1, q2, q3;
output will be like this..
+----------+---------------+-------------+------------------+-----------+----------------+
| q1.dept | q1.deptcount | q2.country | q2.countrycount | q3.desig | q3.desigcount |
+----------+---------------+-------------+------------------+-----------+----------------+
| dir | 2 | canada | 1 | hr | 2 |
| dir | 2 | usa | 2 | hr | 2 |
| dir | 2 | canada | 1 | it | 1 |
| dir | 2 | usa | 2 | it | 1 |
| human | 1 | canada | 1 | hr | 2 |
| human | 1 | usa | 2 | hr | 2 |
| human | 1 | canada | 1 | it | 1 |
| human | 1 | usa | 2 | it | 1 |
+----------+---------------+-------------+------------------+-----------+----------------+
I'm trying to get a query going that would update the parent_id row to reflect the corresponding username that possesses the same member_id as the parent_id.
Below is a representation of the db_name.members table, and I want to convert the parent_ids into their corresponding usernames.
+--------+----------+-----------+-----------+
| name | username | member_id | parent_id |
+--------+----------+-----------+-----------+
| Jeff | Jeff | 167 | NULL |
| Asia | Asia | 143 | NULL |
| Bogart | Bogart | 389 | 167 |
| Greg | Greg | 894 | NULL |
| Hatsy | Hatsy | 328 | 167 |
| Super | Super | 721 | NULL |
| Goku | Goku | 534 | 894 |
| Banana | Banana | 520 | NULL |
| Kyle | Kyle | 456 | 520 |
+--------+----------+-----------+-----------+
What it should look like after:
+--------+----------+-----------+-----------+
| name | username | member_id | parent_id |
+--------+----------+-----------+-----------+
| Jeff | Jeff | 167 | NULL |
| Asia | Asia | 143 | NULL |
| Bogart | Bogart | 389 | Jeff |
| Greg | Greg | 894 | NULL |
| Hatsy | Hatsy | 328 | Jeff |
| Super | Super | 721 | NULL |
| Goku | Goku | 534 | Greg |
| Banana | Banana | 520 | NULL |
| Kyle | Kyle | 456 | Banana |
+--------+----------+-----------+-----------+
This is my current (not working) query:
UPDATE members SET parent_id=(SELECT name FROM members WHERE member_id=parent_id);
You can use this, using a UPDATE with INNER JOIN:
UPDATE members m1 INNER JOIN members m2 ON m1.parent_id = m2.member_id
SET m1.parent_id = m2.username
Keep in mind that in case the parent_id column is a integer / numeric column you can't set the username to this column. You can use a SELECT instead of a UPDATE:
SELECT m1.name, m1.username, m1.member_id, m2.username AS parent_username
FROM members m1 LEFT JOIN members m2 ON m1.parent_id = m2.member_id
demo on dbfiddle.uk
I have the following tables,
select * from department;
+--------------+--------------+--------+------------+---------------+
| departmentid | name | budget | startdate | administrator |
+==============+==============+========+============+===============+
| 101 | Computer Sci | 1000 | 2010-12-26 | XYZ |
| 102 | ECE | 500 | 2015-02-15 | ABC |
| 103 | EEE | 1500 | 2016-08-25 | PQR |
| 104 | Mech | 2500 | 2017-08-22 | LMN |
+--------------+--------------+--------+------------+---------------+
select * from course;
+----------+-------------------+---------+--------------+
| courseid | title | credits | departmentid |
+==========+===================+=========+==============+
| 1001 | Data structures | 12 | 101 |
| 1002 | Algorithms | 12 | 101 |
| 1003 | Graphics | 20 | 101 |
| 2001 | DSP | 20 | 102 |
| 2002 | Matlab | 20 | 102 |
| 2003 | Maths | 10 | 102 |
| 3001 | CAD | 10 | 104 |
| 4001 | Power electronics | 10 | 103 |
| 4002 | Semi conductors | 20 | 103 |
+----------+-------------------+---------+--------------+
select * from student_grade;
+--------------+----------+----------+-------+
| enrollmentid | courseid | personid | grade |
+==============+==========+==========+=======+
| 1 | 1001 | 1 | A |
| 2 | 1002 | 1 | B |
| 3 | 1003 | 1 | A |
| 4 | 3001 | 3 | A |
| 5 | 3001 | 2 | B |
| 6 | 4001 | 4 | A |
| 7 | 4002 | 4 | A |
+--------------+----------+----------+-------+
select * from person;
+----------+----------+-----------+------------+----------------+
| personid | lastname | firstname | hiredate | enrollmentdate |
+==========+==========+===========+============+================+
| 1 | Goudar | Anil | 2016-08-16 | 2016-08-17 |
| 2 | Goudar | Sunil | 2018-09-16 | 2018-09-27 |
| 3 | Dambal | Abhi | 2018-05-07 | 2018-06-17 |
| 4 | Desai | Arun | 2018-05-07 | 2018-06-17 |
| 5 | Xam | Sam | 2018-12-08 | 2018-12-08 |
| 6 | Chatpati | Mangal | 2018-10-10 | 2018-10-08 |
| 9 | Shankar | Dev | 2018-10-10 | 2018-10-08 |
| 10 | Shankar | Mahadev | 2018-08-10 | 2018-08-11 |
+----------+----------+-----------+------------+----------------+
Now I am trying to get the department details with number of students belonging to the department.
And here is my query,
select d.departmentid, d.name, sg.personid from department d inner join course c on c.departmentid = d.departmentid inner join student_grade sg on sg.courseid = c.courseid;
+--------------+--------------+----------+
| departmentid | name | personid |
+==============+==============+==========+
| 101 | Computer Sci | 1 |
| 101 | Computer Sci | 1 |
| 101 | Computer Sci | 1 |
| 104 | Mech | 3 |
| 104 | Mech | 2 |
| 103 | EEE | 4 |
| 103 | EEE | 4 |
+--------------+--------------+----------+
But I want to get the count(distinct(personid)) for each department like group by clause. But I am getting the error with the following query.
select d.departmentid, d.name, count(distinct(sg.personid)) from department d inner join course c on c.departmentid = d.departmentid inner join student_grade sg on sg.courseid = c.courseid;
Cannot use non GROUP BY column 'departmentid' in query results without an aggregate function
Please help me, where I am going wrong.
you have to use group by as you used aggregate funtion
select d.departmentid, d.name,
count(distinct(sg.personid))
from department d inner join course c on c.departmentid = d.departmentid inner join student_grade sg on sg.courseid = c.courseid;
group by d.departmentid, d.name
Use this:-
select d.departmentid, d.name, count(distinct(sg.personid)) from department d inner join course c on c.departmentid = d.departmentid inner join student_grade sg on sg.courseid = c.courseid group by d.departmentid, d.name;
I have three tables college_details, college_courses, course of which college_courses is an intermediate table for many to many relation ships between college_details and course.
college_details
+------------+--------------+
| college_id | college_name |
+------------+--------------+
| 1 | abc, Nagpur |
| 2 | xyz, Nagpur |
| 3 | mnop, Nagpur |
+------------+--------------+
college_courses
+------------+--------------+
| college_id | course_id |
+------------+--------------+
| 1 | 1 |
| 1 | 5 |
| 2 | 3 |
| 3 | 5 |
+---------------------------+
course
+----------+-------------+
|course_id | course_name |
+----------+-------------+
| 1 | B.E |
| 2 | M.E |
| 3 | M.Tech |
| 4 | B.Tech |
| 5 | M.B.A |
+----------+-------------+
SELECT cd.college_id
, cd.college_name
, c.course_name
FROM college_details AS cd
LEFT
JOIN college_courses AS cc
ON cc.college_id = cd.college_id
LEFT
JOIN course AS c
ON cc.course_id = c.course_id
From the above query I get the following table.
+------------+---------------+-------------+
| college_id | college_name | course_name |
+------------+---------------+-------------+
| 1 | abc, college | be |
| 1 | abc, college | mba |
| 2 | xyz, college | me |
| 3 | mnop, college | btech |
+------------+---------------+-------------+
query -> "SELECT cd.college_id,cd.college_name,GROUP_CONCAT(c.course_name) FROM college_details AS cd LEFT JOIN college_courses AS cc ON cc.college_id = cd.college_id LEFT JOIN course AS c ON cc.college_id = c.course_id ";
And from above query I get the following table.
+------------+--------------+-----------------------------+
| college_id | college_name | GROUP_CONCAT(c.course_name) |
+------------+--------------+-----------------------------+
| 1 | abc, college | be,be,me,btech |
+------------+--------------+-----------------------------+
But what I want is the following table.
+------------+---------------+-------------+
| college_id | college_name | course_name |
+------------+---------------+-------------+
| 1 | abc, college | be,mba |
| 2 | xyz, college | me |
| 3 | mnop, college | btech |
+------------+---------------+-------------+
I have the following tables:
clients:
| id | name | code | zone |
--------------------------------
| 1 | client 1 | a1b1 | zone1|
| 2 | client 2 | a2b2 | zone2|
contacts:
| id_contact | first_name | last_name |
----------------------------------------
| 11 | first1 | last1 |
| 22 | first2 | last2 |
| 33 | first3 | last3 |
| 44 | first4 | last4 |
client_contacts:
| id_client | id_contact |
--------------------------
| 1 | 11 |
| 1 | 22 |
| 1 | 33 |
| 2 | 11 |
| 2 | 44 |
offers:
| id_offer | id_client | value |
--------------------------
| 111 | 1 | 100 |
| 222 | 1 | 200 |
| 333 | 1 | 300 |
| 444 | 2 | 400 |
I would like through a optimal select to obtain:
| id_client | name | code | zone | contacts_pers | total_offer_value |
----------------------------------------------------------------------------
| 1 | client 1 | a1b1 | zone1 | first1 last1; | 600 |
first2 last2;
first3 last3;
| 2 | client 2 | a2b2 | zone2 | first1 last1; | 400 |
first4 last4;
I know how to get the desired result with "group_concat" and stored procedures for "total_offer_value". But how to get the desired result from a single efficient select?
SELECT c.id, c.name, c.code, c.zone, GROUP_CONCAT(DISTINCT CONCAT(co.first_name, " ", c.last_name) SEPARATOR ";") AS contact_pers, func_total_offer_value(c.id) AS total_offer_value
FROM clients c
LEFT OUTER JOIN (client_contacts cc, contacts co) ON ( c.id = cc.id_client AND cc.id_contact = co.id_contact )
GROUP BY c.id