Complex SQL query - oracle

There is a customer table. I want to list active and inactive status in one query. How can I do this?
SELECT count(*) as ACTIVE,
count(*) as INACTIVE
FROM V_CUSTOMER
WHERE STATUS='a' AND STATUS='i'

We can use CASE statement to translate the two values of STATUS:
SELECT
sum(case when STATUS = 'a' then 1 else 0 end) as ACTIVE
, sum(case when STATUS = 'd' then 1 else 0 end) as DEACTIVE
FROM V_CUSTOMER
There is no need for a WHERE clause unless there are a large number of records with other values for STATUS, in which case use OR instead of AND:
WHERE STATUS='a' OR STATUS='d'

Try using group by:
SELECT count(*), STATUS FROM V_CUSTOMER
Where STATUS='a' OR STATUS='d'
GROUP BY STATUS

SELECT count(decode(status,'a',1)) as ACTIVE,
count(decode(status,'d',1)) as DEACTIVE
FROM V_CUSTOMER
WHERE STATUS='a' or STATUS='d'

I think you'll need something like this:
select Status, count(*) from V_Customer
where STATUS='a' or STATUS='d'
group by STATUS
This will give you the number of records per status.

Related

FOR LOOP Statement in BigQuery

I have data in two tables:
Table activity:
User_ID Event_Time Cmd
AMsySZb9GPcL 1512125190721078 1
AMsySZYQ-lAI 1512118629594674 0
AMsySZZMlPzD 1512125736366076 1
....
Table behaviour:
User_ID Event_Time
AMsySZZFezm 1512145788526664
AMsySZb9GPcL 1512125190721078
AMsySZY5YcTa 1512143509733637
AMsySZYQ-lAI 1512118629594674
AMsySZZMlPzD 1512125736366076
....
User_ID is type STRING, Event_Time is type INTEGER.
Step 1: The basic SELECT statement I am making now is:
SELECT activity.User_ID, activity.Event_Time FROM activity WHERE Cmd=1
Step 2: Then I would like to get data from behaviour table, but only for Users from Step 1 and only where behaviour.Event_Time is before activity.Event_Time.
For example:
From Step 1 I got User_ID='AMsySZb9GPcL' and I need:
SELECT behaviour.User_ID, behaviour.Event_Time
FROM behaviour
WHERE User_ID='AMsySZb9GPcL' AND activity.Event_Time >= behaviour.Event_Time
But the problem is that I have to do the same for every User_ID from Step 1, I am not sure if it is the supported functionality of SQL, but I need something like FOR LOOP.
You don't need FOR LOOP for this - you should think of set based operation when you deal with SQL of any sort - so you can process all your users in one shot using power of JOINs
Below is for BigQuery Standard SQL
#standardSQL
SELECT
activity.User_ID User_ID,
activity.Event_Time activity_Time,
behaviour.Event_Time behaviour_Time
FROM `project.dataset.activity` activity
JOIN `project.dataset.behaviour` behaviour
ON activity.User_ID = behaviour.User_ID
AND activity.Event_Time >= behaviour.Event_Time
WHERE Cmd = 1
You can test / play with above using dummy data from your example:
#standardSQL
WITH `project.dataset.activity` AS (
SELECT 'AMsySZb9GPcL' User_ID, 1512125190721078 Event_Time, 1 Cmd UNION ALL
SELECT 'AMsySZYQ-lAI', 1512118629594674, 0 UNION ALL
SELECT 'AMsySZZMlPzD', 1512125736366076, 1
), `project.dataset.behaviour` AS (
SELECT 'AMsySZZFezm ' User_ID, 1512145788526664 Event_Time UNION ALL
SELECT 'AMsySZb9GPcL', 1512125190721078 UNION ALL
SELECT 'AMsySZY5YcTa', 1512143509733637 UNION ALL
SELECT 'AMsySZYQ-lAI', 1512118629594674 UNION ALL
SELECT 'AMsySZZMlPzD', 1512125736366076
)
SELECT
activity.User_ID User_ID,
activity.Event_Time activity_Time,
behaviour.Event_Time behaviour_Time
FROM `project.dataset.activity` activity
JOIN `project.dataset.behaviour` behaviour
ON activity.User_ID = behaviour.User_ID
AND activity.Event_Time >= behaviour.Event_Time
WHERE Cmd=1

ORA-00907 Missing Right Parenthesis (Oracle)

I was previously holding my data in SharePoint. At that time, the below query ran fine :-
SELECT Nz(Abs(Sum(sales_route="Sales Mailbox")),0) AS AcceptDirect
FROM tblQuotesNew AS t1;
Now that I have moved my data to Oracle (but still retrieving it via Access), I get the error ORA-00907 Missing Right Parenthesis.
Can anyone suggest how I can modify the code above that that it is acceptable to Oracle?
Thanks in advance
I think your query counts number of rows with sales_route as 'Sales Mailbox' which can be simply written as:
select count(*) as AcceptDirect
from tblQuotesNew
where sales_route = 'Sales Mailbox';
If you want counts for different routes in the same query, you can do something like this:
select count(case when sales_route = 'Sales Mailbox' then 1 end) as AcceptDirect,
count(case when sales_route = 'XYZ' then 1 end) as XYZ
from tblQuotesNew
where sales_route in ('Sales Mailbox', 'XYZ');

ORDER BY CASE WHEN: ORDER BY items must appear in the select list

I have this example code of something I'm trying to run. Only he table names and column names were changed. What I want to do is have a result set of states and have 'NULL' be the first value and the rest of the results appear below 'NULL' in ascending order and I can't for the life of me make it work. I get the error at the bottom. This may be a very "noobish" question, but can anyone help? Much appreciated everyone!
SELECT DISTINCT
State
FROM TABLE1 (NOLOCK)
WHERE COLUMN1 NOT LIKE '%THAT%'
AND COLUMN1 NOT LIKE '%THIS%'
UNION
SELECT 'NULL'
ORDER BY ( CASE WHEN State = 'NULL' THEN 0
ELSE 1
END );
Error Message:
ORDER BY items must appear in the select list if the statement contains a UNION, INTERSECT or EXCEPT operator.
You need to select that column... even if you don't use it later, the order by requires it to be present in the select.
SELECT DISTINCT
State,
CASE WHEN State = 'NULL' THEN 0
ELSE 1 END orderId
FROM TABLE1 (NOLOCK)
WHERE COLUMN1 NOT LIKE '%THAT%'
AND COLUMN1 NOT LIKE '%THIS%'
ORDER BY ( CASE WHEN State = 'NULL' THEN 0
ELSE 1
END );

Aggregated column use in Hive Query

My hive table (tab1) structure:
people_id,time_spent,group_type
1,234,a
2,540,b
1,332,a
2,112,b
Below is the query i am trying to execute but getting error ("Not yet supported place for UDAF 'sum'"):
select people_id, sum(case when group_type='a' then time_spent else 0 end) as a_time, sum(pow(a_time,2)) as s_sq_a_time,sum(case when group_type='b' then time_spent else 0 end) as b_time, sum(pow(b_time,2)) as s_sq_b_time from tab1 group by people_id;
Is it possible to refer aggregated column from same select statement in Hive?
I have also referred below link but it didnt work:
http://grokbase.com/t/hive/user/095tpdkrgz/built-in-aggregate-function-standard-deviation#
Set an alias for the table name and use the table alias when accessing the columns.
E.g.
select startstation, count(tripid) as a
from 201508_trip_data as t
group by t.startstation
Note 't' is the alias for the table and I've used t.startstation to access the
You'll have to use a derived table to refer to a_time and b_time
select a_time, b_time,
pow(a_time,2) as s_sq_a_time,
pow(b_time,2) as s_sq_b_time
from (
select people_id,
sum(case when group_type='a' then time_spent else 0 end) as a_time,
sum(case when group_type='b' then time_spent else 0 end) as b_time
from tab1 group by people_id
) t1

oracle procedure cursor query when case statement

CURSOR BULKUPDATE IS
SELECT SUM(B.ACCOUNT_BALANCE) AS ACCOUNT_BALANCE,C.CIF AS CIF_ID FROM _ACCOUNTS_STAGING2 B JOIN _RELATION_STAGING2 C
ON B.ACCOUNT_IDENTIFICATION_NUMBER = C.ACCOUNT_IDENTIFICATION_NUMBER AND B.SOURCEID=C.SOURCEID JOIN _CUSTOMER_STAGING2 A ON A.CIF=C.CIF AND A.SOURCEID=C.SOURCEID WHERE C.ROLE_ON_ACCOUNT IN
(Select Rollonaccount From _Roleaccount_Master Where Aggregatebalance='Y')
And upper(B.Scheme_Type) In (Select Scheme_Type From _Schema_Type_Master Where
Depository_Account = 'Y') Group By C.Cif;
Rec_Bulkupdate Bulkupdate%Rowtype;
I am using this query to sum account balances based on different cif and source. The question is I want to calculate four different types of sum on the basis of _Schema_Type_Master. For example I want to check now current_account='Y' instead of Depository_Account='Y'
_ACCOUNTS_STAGING2 B JOIN _RELATION_STAGING2 C
ON B.ACCOUNT_IDENTIFICATION_NUMBER = C.ACCOUNT_IDENTIFICATION_NUMBER AND B.SOURCEID=C.SOURCEID JOIN _CUSTOMER_STAGING2 A ON A.CIF=C.CIF AND A.SOURCEID=C.SOURCEID WHERE C.ROLE_ON_ACCOUNT IN
(Select Rollonaccount From _Roleaccount_Master Where Aggregatebalance='Y')
And upper(B.Scheme_Type) In (Select Scheme_Type From _Schema_Type_Master Where
current_account='Y') Group By C.Cif;
Rec_Bulkupdate Bulkupdate%Rowtype;
Is there any way or do I need to write four different cursors for that??
You can remove dipository_account='Y' and current_account='Y' and use case in select as -
SELECT SUM(CASE WHEN Depository_Account = 'Y' THEN B.ACCOUNT_BALANCE ELSE 0 END) AS DIPOSITORY_ACCOUNT_BALANCE,
SUM(CASE WHEN current_account = 'Y' THEN B.ACCOUNT_BALANCE ELSE 0 END) AS CURRENT_ACCOUNT_BALANCE
and then rest of your code. You will get two different columns for sum of Depository account and Current account.
And if filter for dipository_account='Y' and current_account='Y' is required, then use them in where condition with or operator :
AND (dipository_account='Y' or current_account='Y')

Resources