hive scan and select in one query - hive

I have a hive table, say emp_details(name, dept).
In this table, I need to check if any records exists with dept = ‘a’ then select those records. If no such record is found then only I will choose records with dept = ‘b’. The source data has either 'a' or 'b' as dept value and my result set will contain either 'a' or 'b' not both.
The problem is I am bound to use only one hive query for this issue.

Calculate a_exist flag and use it for filtering:
select name, dept
from
(select name,
dept,
(count(case when dept='a' then 1 end) over()>0) as a_exist
from test_a
)a
where (a_exist and dept='a') --only a if exists
or ((NOT a_exist)and dept='b') --return b if a not exists
;

Related

Exclude rows where ID is duplicated but 3rd column has "unknown

I have this dataset where there are rows with duplicate personIDs but different pcpgrouper2. I only want to exclude "Unknown" where there are more than 1 of the same PersonID and one of them is "Unknown". If the ID has only one row with "Unknown" then keep that row.
Name
PersonID
PCPGrouper
ABBAN, AVRIL
1094893
Unknown
ABBIS,CHLOE
1114294
T Docs
ABBIS,CHLOE
1114294
Unknown
We can try using the following SQL query (assuming you are using SQL):
SELECT Name, PersonID, PCPGrouper
FROM yourTable t1
WHERE PCPGrouper != 'Unknown' OR
NOT EXISTS (
SELECT 1
FROM yourTable t2
WHERE t2.PersonID = t1.PersonID AND
t2.PCPGrouper != 'Unknown'
);
The above logic retains any person record whose grouper value is not unknown or is unknown but there is no other value.

sql to update table for multiple columns.?

I have an EMP table with columns like id,name,job,salary,age,doj.
This EMP table has 10 records, with IDs id1,id2....id10.
I need a DML statement to update names for 4 IDs ( id2,id4, id6, id8).
This requires multiple where conditions.
Such as -
name=a where id=id2
name=b where id=id4.
Please suggest.
You can use a case expression. That should look like:
update emp
set name = case id
when 'id2' then 'a'
when 'id4' then 'b'
when 'id6' then 'c'
when 'id8' then 'd'
end
where id in ('id2', 'id4', 'id6', 'id8')

how to update multiple rows in oracle

I would like to update multiple rows with different values for all different records, but don't have any idea how to do that, i am using below sql to update for single record but i have 200 plus records to update
update employee
set staff_no = 'ab123'
where depno = 1
i have 50 dep and within those dep i need to update 200 plus staff no. any idea.
At the moment if i just do a
select * from Departments
i can see list of all employee which needs staff no updating.
UPDATE person
SET staff_no =
CASE person_no
WHEN 112 THEN 'ab123'
WHEN 223 THEN 'ab324'
WHEN 2343 THEN 'asb324'
and so on.....
END
You should be able to use MERGE statement to do it in a single shot. However, the statement is going to be rather large:
MERGE INTO employee e
USING (
SELECT 1 as d_id, 'cd234' as staff_no FROM Dual
UNION ALL
SELECT 2 as d_id, 'ef345' as staff_no FROM Dual
UNION ALL
SELECT 3 as d_id, 'fg456' as staff_no FROM Dual
UNION ALL
... -- More selects go here
SELECT 200 as d_id, 'za978' as staff_no FROM Dual
) s
ON (e.depno = S.d_id)
WHEN MATCHED THEN UPDATE SET e.staff_no= s.staff_no
use a case expression
UPDATE employee
SET staff_no =
CASE depno
WHEN 1 THEN 'ab123'
WHEN 2 THEN 'ab321'
--...
ELSE staff_no
END
WHERE depno IN ( 1, 2 ) -- list all cases here. use a subquery if you don't want to / cannot enumerate
For conditional update, you could use multiple update statements, or use CASE expression in the SET clause.
Something like,
UPDATE table
SET schema.column = CASE
WHEN column1= 'value1' AND column2='value2' THEN
'Y'
ELSE
'N'
END
I wish you tried to search for a similar question on this site, there was a recent question and this was my answer.
If you have two tables like:
CREATE TABLE test_tab_1 (id NUMBER, name VARCHAR2(25));
CREATE TABLE test_tab_2 (id NUMBER, name VARCHAR2(25));
You can use UPDATE statement as below:
UPDATE test_tab_1
SET test_tab_1.name = (SELECT test_tab_2.name FROM test_tab_2
WHERE test_tab_1.id = test_tab_2.id);

Copy column from one database to another and insert data depends on condition in SQL Server

I have two databases on the same SQL server. The first is named Aa with a table Models in which there are two columns: Id and Desc and Bb database with a table ListOfModels in which there are three columns: Id, MachineTypeId, ModelName. I need to copy all Desc values from Aa database into ModelName in Bb and insert 1 into MachineTypeId if Desc starts with "K", otherwise insert 2.
Can you please help me write the script for this?
The question is unclear as to whether you want to insert new rows into the table or just update matching values.
If you actually want to insert records:
insert into bb..ListOfModels(MachineTypeId, ModelName)
select (case when TypeId like 'K%' then 1 else 2 end), m.[desc]
from aa..Models m;
If you want to update the records based on matching by id:
update lom
set ModelName = [desc],
MachineTypeId = (case when m.TypeId like 'K%' then 1 else 2 end)
from bb..ListOfModels lom join
aa..Models m
on lom.id = m.id;
By the way, desc is a lousy name for a column, because it is a reserved word in SQL.
Use a case statement: http://msdn.microsoft.com/en-us/library/ms181765.aspx
Case Substr(MachineTypeID,1,1) When "K" Then 1 Else 2 End

Count(*) with 0 for boolean field

Let's say I have a boolean field in a database table and I want to get a tally of how many are 1 and how many are 0. Currently I am doing:
SELECT 'yes' AS result, COUNT( * ) AS num
FROM `table`
WHERE field = 1
UNION
SELECT 'no' AS result, COUNT( * ) AS num
FROM `table`
WHERE field = 0;
Is there an easier way to get the result so that even if there are no false values I will still get:
----------
|yes | 3 |
|no | 0 |
----------
One way would be to outer join onto a lookup table. So, create a lookup table that maps field values to names:
create table field_lookup (
field int,
description varchar(3)
)
and populate it
insert into field_lookup values (0, 'no')
insert into field_lookup values (1, 'yes')
now the next bit depends on your SQL vendor, the following has some Sybase (or SQL Server) specific bits (the outer join syntax and isnull to convert nulls to zero):
select description, isnull(num,0)
from (select field, count(*) num from `table` group by field) d, field_lookup fl
where d.field =* fl.field
you are on the right track, but the first answer will not be correct. Here is a solution that will give you Yes and No even if there is no "No" in the table:
SELECT 'Yes', (SELECT COUNT(*) FROM Tablename WHERE Field <> 0)
UNION ALL
SELECT 'No', (SELECT COUNT(*) FROM tablename WHERE Field = 0)
Be aware that I've checked Yes as <> 0 because some front end systems that uses SQL Server as backend server, uses -1 and 1 as yes.
Regards
Arild
This will result in two columns:
SELECT SUM(field) AS yes, COUNT(*) - SUM(field) AS no FROM table
Because there aren't any existing values for false, if you want to see a summary value for it - you need to LEFT JOIN to a table or derived table/inline view that does. Assuming there's no TYPE_CODES table to lookup the values, use:
SELECT x.desc_value AS result,
COALESCE(COUNT(t.field), 0) AS num
FROM (SELECT 1 AS value, 'yes' AS desc_value
UNION ALL
SELECT 2, 'no') x
LEFT JOIN TABLE t ON t.field = x.value
GROUP BY x.desc_value
SELECT COUNT(*) count, field FROM table GROUP BY field;
Not exactly same output format, but it's the same data you get back.
If one of them has none, you won't get that rows back, but that should be easy enough to check for in your code.