0% found this document useful (0 votes)
101 views69 pages

Hive Practice July

HQL is Hive's query language that is similar to SQL. It allows users to perform CRUD (create, read, update, delete) operations on tables stored in the Hive data warehouse. The document shows examples of creating tables, inserting data, and running select queries to retrieve data from the tables. It also provides an overview of Hive's data types like string, numeric, date/time, and built-in functions.

Uploaded by

Siva Pavan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
101 views69 pages

Hive Practice July

HQL is Hive's query language that is similar to SQL. It allows users to perform CRUD (create, read, update, delete) operations on tables stored in the Hive data warehouse. The document shows examples of creating tables, inserting data, and running select queries to retrieve data from the tables. It also provides an overview of Hive's data types like string, numeric, date/time, and built-in functions.

Uploaded by

Siva Pavan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 69

HQL – HIVE Query Language

SQL Statements and Categorization

Structured query language is a collection of various types of statements shown in the table below.

Table 2: Various statements of SQL

SELECT Data retrieval or Data query


INSERT
UPDATE Data manipulation language(DML)
DELETE
MERGE
CREATE
ALTER
DROP Data definition language (DDL)
RENAME
TRUNCATE
CREATE TABLE EMP
(EMPNO int ,
ENAME VARCHAR(10),
JOB VARCHAR(9),
MGR int,
HIREDATE date,
SAL int,
COMM int,
DEPTNO int);

INSERT INTO EMP VALUES


(7369, 'SMITH', 'CLERK', 7902,
CAST('1980-12-17' as DATE), 800, NULL, 20);
INSERT INTO EMP VALUES
(7499, 'ALLEN', 'SALESMAN', 7698,
CAST('1981-02-20' as DATE), 1600, 300, 30);
INSERT INTO EMP VALUES
(7521, 'WARD', 'SALESMAN', 7698,
CAST('1981-02-22' as DATE), 1250, 500, 30);
INSERT INTO EMP VALUES
(7566, 'JONES', 'MANAGER', 7839,
CAST('1981-04-02' as DATE), 2975, NULL, 20);
INSERT INTO EMP VALUES
(7654, 'MARTIN', 'SALESMAN', 7698,
CAST('1981-09-28' as DATE), 1250, 1400, 30);
INSERT INTO EMP VALUES
(7698, 'BLAKE', 'MANAGER', 7839,
CAST('1981-05-01' as DATE), 2850, NULL, 30);
INSERT INTO EMP VALUES
(7782, 'CLARK', 'MANAGER', 7839,
CAST('1981-06-09' as DATE), 2450, NULL, 10);
INSERT INTO EMP VALUES
(7788, 'SCOTT', 'ANALYST', 7566,
CAST('1982-12-09' as DATE), 3000, NULL, 20);
INSERT INTO EMP VALUES
(7839, 'KING', 'PRESIDENT', NULL,
CAST('1981-11-17' as DATE), 5000, NULL, 10);
INSERT INTO EMP VALUES
(7844, 'TURNER', 'SALESMAN', 7698,
CAST('1981-09-08' as DATE), 1500, NULL, 30);
INSERT INTO EMP VALUES
(7876, 'ADAMS', 'CLERK', 7788,
CAST('1983-01-12' as DATE), 1100, NULL, 20);
INSERT INTO EMP VALUES
(7900, 'JAMES', 'CLERK', 7698,
CAST('1981-12-03' as DATE), 950, NULL, 30);

INSERT INTO EMP VALUES


(7902, 'FORD', 'ANALYST', 7566,
CAST('1981-12-03' as DATE), 3000, NULL, 20);
INSERT INTO EMP VALUES
(7934, 'MILLER', 'CLERK', 7782,
CAST('1982-01-23' as DATE), 1300, NULL, 10);

CREATE TABLE DEPT


(DEPTNO INT,
DNAME VARCHAR(14),
LOC VARCHAR(13) );

INSERT INTO DEPT VALUES (10, 'ACCOUNTING', 'NEW YORK');


INSERT INTO DEPT VALUES (20, 'RESEARCH', 'DALLAS');
INSERT INTO DEPT VALUES (30, 'SALES', 'CHICAGO');
INSERT INTO DEPT VALUES (40, 'OPERATIONS', 'BOSTON');
HIVE Primitive Data Types

The different categories of Primitive Data Types are as follows

* Numeric Data Types


* String Data Types
* Date/Time Data Types
* Miscellaneous Data Types
* Numeric Data Types

Different Numeric Data Types supported in Hive are


=============================================
INTEGRAL TYPES
-------------
TINYINT (1-byte signed integer, from -128 to 127)
SMALLINT (2-byte signed integer, from -32,768 to 32,767)
INT/INTEGER (4-byte signed integer, from -2,147,483,648 to 2,147,483,647)
BIGINT (8-byte signed integer, from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807)
FLOATING TYPES

FLOAT (4-byte single precision floating point number)


DOUBLE (8-byte double precision floating point number)
DOUBLE PRECISION (This is an alias of Double)
DECIMAL (precision ,scale)
NUMERIC (same as DECIMAL from Hive 3.0)

Points to keep in mind for Numeric Datatype:


-------------------------------------------
* When we provide a number , Hive by default considers it to be of Integer Data Type.
* When the number is bigger than Integer Range, Hive automatically considers it as BigInt.
* If we want to specify that the number is of different Type then we need to assign Post Fix.
* To specify that its TINYINT , post fix the Integer with Y. Ex 20Y.
* To specify that its SMALLINT , post fix the Integer with S. Ex 20S.
* To specify that its BIGINT , post fix the Integer with L. Ex 20L.
The default datatype of DECIMAL is (10,0) when precision and scale are not defined. And max precision
allowed is 38.
String Data Types

Hive supports 3 types of String Datatypes CHAR ,VARCHAR ,STRING.


------------------------------------------------------------------

* CHAR – Similar to other programming languages this is of fixed length. If you define char(10) and the input
value is of 6 characters then the remaining 4 will be filled with spaces.
* VARCHAR – This works similar to CHAR but instead of fixed length this takes variable length. If you define
varchar(10) and the input value is of 6 characters then only 6 bytes will be used and no additional space will
be blocked. If the string length is greater than the precision, then the value is truncated and displayed.
* STRING – Strings are expressed with single quotes ( ‘ ‘ ) or double quotes ( ” ” ). The maximum length of
String is debatable but i found a good answer in StackOverflow for this which suggest it could be 2 GB.

Date/Time Data Types


----------------------
Hive supports 3 types TIMESTAMP , DATE and INTERVAL.

* TIMESTAMP – Supports UNIX timestamp with optional nanosecond precision. ex: 2020-011-21
08:46:05.296
* If input is of type Integer ,it is interpreted as UNIX timestamp in seconds
* If input is of type Floating Point ,it is interpreted as UNIX timestamp in seconds with decimal precision
* If input is of type String, it follows java.sql.Timestamp format “YYYY-MM-DD HH:MM:SS.fffffffff” (9 decimal
place precision)
* DATE – It specifies the date in YEAR / MONTH /DATE format as YYYY-MM-DD. It does not store any time
value.
Note that you can convert Timestamp and String to Date. And also Date to Timestamp and String.

Miscellaneous Data Types


Hive supports 2 miscellaneous data types Boolean and Binary.

Boolean – Accepts TRUE or FALSE.


Binary – This stores array of bytes.
Data Retrieval or Data Query using SELECT statement

It is a building block for data retrieval in SQL. This statement helps to retrieve data from one or multiple
tables and produce output in a well formatted manner.

Syntax : SELECT <COLUMNS> FROM <TABLE>;

Your First Query

INPUT:
SQL> SELECT * FROM emp;

OUTPUT:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
--
--
-- ---------- --------- ---------- --------- ---------- ---------- ----------
73
69 SMITH CLERK 7902 17-DEC-80 800 20
74
99 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
75
21 WARD SALESMAN 7698 22-FEB-81 1250 500 30
75
66 JONES MANAGER 7839 02-APR-81 2975 20
76
54 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
76
98 BLAKE MANAGER 7839 01-MAY-81 2850 30
77
82 CLARK MANAGER 7839 09-JUN-81 2450 10
77
88 SCOTT ANALYST 7566 09-DEC-82 3000 20
78
39 KING PRESIDENT 17-NOV-81 5000 10
78
44 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
78
76 ADAMS CLERK 7788 12-JAN-83 1100 20
79
00 JAMES CLERK 7698 03-DEC-81 950 30
79
02 FORD ANALYST 7566 03-DEC-81 3000 20
79
34 MILLER CLERK 7782 23-JAN-82 1300 10

ANALYSIS:

Notice that columns 6 and 8 in the output statement are right justified and that
columns 2 and 3 are left justified. This format follows the alignment convention in
which numeric data types are right justified and character data types are left
justified.

The asterisk (*) in select * tells the database to return all the columns associated
with the given table described in the FROM clause. The database determines the order
in which to return the columns.

A full table scan is used whenever there is no where clause on a query.

Terminating an SQL Statement

In some implementations of SQL, the semicolon at the end of the statement tells the interpreter that
you are finished writing the query. For example, Oracle's SQL*PLUS won't execute the query until it finds
a semicolon (or a slash). On the other hand, some implementations of SQL do not use the semicolon as a
terminator. For example, Microsoft Query and Borland's ISQL don't require a terminator, because your
query is typed in an edit box and executed when you push a button.
Changing the Order of the Columns

We can change the order of selection of columns

INPUT:

SQL> SELECT empno, ename, sal, job, comm FROM emp;

OUTPUT:

EMPNO ENAME SAL JOB COMM


-------- ---------- ---------- ---------
-- ----------
7369 SMITH 800 CLERK
7499 ALLEN 1600 SALESMAN 300
7521 WARD 1250 SALESMAN 500
7566 JONES 2975 MANAGER
7654 MARTIN 1250 SALESMAN 1400
7698 BLAKE 2850 MANAGER
7782 CLARK 2450 MANAGER
7788 SCOTT 3000 ANALYST
7839 KING 5000 PRESIDENT
7844 TURNER 1500 SALESMAN 0
7876 ADAMS 1100 CLERK
7900 JAMES 950 CLERK
7902 FORD 3000 ANALYST
7934 MILLER 1300 CLERK

14 rows selected.

ANALYSIS:

Observe that the column sequence specified in the select command is not the original
sequence followed during table creation. Also as per sql a column may be selected
any number of times in the same select command.

Expressions, Conditions, and Operators

Expressions

The definition of an expression is simple: An expression returns a value. Expression types are very broad,
covering different data types such as String, Numeric, and Boolean. In fact, pretty much anything
following a clause (SELECT or FROM, for example) is an expression. In the following example amount is
an expression that returns the value contained in the amount column.

SELECT sal FROM emp;

In the following statement NAME, DESIGNATION, SAL are expressions:

SELECT ENAME, DESIGNATION, SAL FROM EMP;

Now, examine the following expression:

WHERE ENAME = 'KING'

It contains a condition, ENAME = 'KING', which is an example of a Boolean expression. ENAME =


'KING' will be either TRUE or FALSE, depending on the condition =.
Conditions

If you ever want to find a particular item or group of items in your database, you need one or more
conditions. Conditions are contained in the WHERE clause. In the preceding example, the condition is
ENAME = 'KING'

To find everyone in your organization who worked more than 100 hours last month, your condition
would be SAL > 2000

Conditions enable you to make selective queries. In there most common form, conditions comprise a
variable, a constant, and a comparison operator. In the first example the variable is E NAME, the constant
is 'KING', and the comparison operator is =.

In the second example the variable is SAL, the constant is 100, and the comparison operator is >. You
need to know about two more elements before you can write conditional queries: the WHERE clause and
operators.

The WHERE Clause

Syntax: SELECT <COLUMNS> FROM <TABLE> WHERE <SEARCH CONDITION>;

SELECT, FROM, and WHERE are the three most frequently used clauses in SQL. WHERE simply
causes your queries to be more selective. Without the WHERE clause, the most useful thing you could
do with a query is display all records in the selected table(s).

If you wanted a particular EMPLOYEE, you could type

INPUT:
SQL> SELECT * FROM emp WHERE ename = 'KING';

OUTPUT:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
------ ---------- --------- ---------- --------- ---------- ---------- ----------
7839 KING PRESIDENT 17-NOV-81 5000 10

ANALYSIS:
This simple example shows how you can place a condition on the data that you want to
retrieve.
If you want a particular EMPLOYEE, you could type

INPUT:
SQL> SELECT * FROM emp WHERE ename != 'KING';
OR
SQL> SELECT * FROM emp WHERE ename <> 'KING';

OUTPUT:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---
---
- ---------- --------- ---------- --------- ---------- ---------- ----------
73
69 SMITH CLERK 7902 17-DEC-80 800 20
74
99 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
75
21 WARD SALESMAN 7698 22-FEB-81 1250 500 30
75
66 JONES MANAGER 7839 02-APR-81 2975 20
76
54 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
76
98 BLAKE MANAGER 7839 01-MAY-81 2850 30
77
82 CLARK MANAGER 7839 09-JUN-81 2450 10
77
88 SCOTT ANALYST 7566 09-DEC-82 3000 20

784
4 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
787
6 ADAMS CLERK 7788 12-JAN-83 1100 20
790
0 JAMES CLERK 7698 03-DEC-81 950 30
790
2 FORD ANALYST 7566 03-DEC-81 3000 20
793
4 MILLER CLERK 7782 23-JAN-82 1300 10

ANALYSIS:

Displays all the employees other than KING.

Operators

Operators are the elements you use inside an expression to articulate how you want specified conditions
to retrieve data. Operators fall into six groups: arithmetic, comparison, character, logical, set, and
miscellaneous.

1. Arithmetic Operators : + , - , / , *
2. Comparison Operators : < , <= , > , >= , ==

3. Character Operators : Like, _ , ||

4. Logical Operators : AND , OR , NOT

5. Miscellaneous Operators: IN, BETWEEN and DISTINCT

Arithmetic Operators

The arithmetic operators are plus (+), minus (-), divide (/), multiply (*).

The first four are self-explanatory. Modulo returns the integer remainder of a division.

Comparison Operators

True to their name, comparison operators compare expressions and return one of three values: TRUE,
FALSE, or Unknown. See the following examples.

200
SELECT FROM emp WHERE sal 0
* >= ;
A
SELECT FROM emp WHERE sal 300 N
* >= 0 D sal <= 4000;
e
SELE FR m WHERE BETWEE 3000
CT * OM p sal N AND 4000;
e
SELE FR m WHERE NOT 300
CT * OM p sal BETWEEN 0 AND 4000;
To understand how you could get an Unknown, you need to know a little about the concept of NULL. In
database terms NULL is the absence of data in a field. It does not mean a column has a zero or a blank in
it. A zero or a blank is a value. NULL means nothing is in that field. If you make a comparison like Field
= 9 and the only value for Field is NULL, the comparison will come back Unknown. Because
Unknown is an uncomfortable condition, most flavors of SQL change Unknown to FALSE and provide a
special operator, IS NULL, to test for a NULL condition.

Here's an example of NULL: Suppose an entry in the PRICE table does not contain a value for

WHOLESALE. The results of a query might look like this:

SELECT * FROM emp WHERE comm IS NULL;

SELECT * FROM emp WHERE comm IS NOT NULL;

Character Operators

You can use character operators to manipulate the way character strings are represented, both in the
output of data and in the process of placing conditions on data to be retrieved. This section describes
two character operators: the LIKE operator and the || operator, which conveys the concept of
character concatenation.
LIKE operator

What if you wanted to select parts of a database that fit a pattern but weren't quite exact matches? You
could use the equal sign and run through all the possible cases, but that process would be time-
consuming. Instead, you could use LIKE.
Consider the following:

INPUT:
SQL> SELECT * FROM emp WHERE ename LIKE ‘A%’;

ANALYSIS:
Displays all the employees whose names begins with letter A

INPUT:
SQL> SELECT * FROM emp WHERE ename NOT LIKE ‘A%’;

ANALYSIS:
Displays all the employees whose names not beginning with letter A

INPUT:
SQL> SELECT * FROM emp WHERE ename LIKE ‘%A%’;

ANALYSIS:
Displays all the employees whose names contains letter A (Any number of A’s)

INPUT:
SQL> SELECT * FROM emp WHERE ename LIKE ‘%A%A%’;

ANALYSIS:
Displays all the names whose name contains letter A more than one time

INPUT:
SQL> SELECT * FROM emp WHERE hiredate LIKE ‘%81’;

ANALYSIS:
Displays all the employees who joined in the year 81.

INPUT:
SQL> SELECT * FROM emp WHERE sal LIKE ‘4%’;

ANALYSIS:
Displays all the employees whose salary begins with number 4. (Implicit data
conversion takes place).

Underscore (_)

The underscore is the single-character wildcard with in the LIKE operator.

INPUT:

SQL> SELECT empno,ename FROM emp WHERE ename LIKE ‘_A%’;

OUTPUT:

EMPNO ENAME
-------- --------
-- --
7521 WARD
7654 MARTIN
7900 JAMES

ANALYSIS:

Displays all the employees whose second letter is A

INPUT:
SQL> SELECT * FROM emp WHERE ename LIKE ‘__A%’;

OUTPUT:
ENAME
----------
BLAKE
CLARK
ADAMS

ANALYSIS:

Displays all the employees whose third letter is A ( Two underscores followed by A)

INPUT:
SQL> SELECT * FROM emp WHERE ename LIKE ‘A%\_%’ ESCAPE „\’;

OUTPUT:
ENAME
----------
AVINASH_K
ANAND_VARDAN
ADAMS_P

ANALYSIS:
Displays all the employees with underscore (_). „\’ Escape character. Underscore is
used to identify a position in the string. To treat _ as a character we have to use
Escape (\) character,
Concatenation ( ||) operator

Used to combine two given strings

INPUT:
SQL> SELECT ename || job FROM emp;

OUTPUT:
ENAME||JOB
-------------------
SMITHCLERK
ALLENSALESMAN
WARDSALESMAN
JONESMANAGER
MARTINSALESMAN
BLAKEMANAGER
CLARKMANAGER
SCOTTANALYST
KINGPRESIDENT
TURNERSALESMAN
ADAMSCLERK
JAMESCLERK
FORDANALYST
MILLERCLERK

ANALYSIS:

Combines both name and designation as a single string.

INPUT:
SQL>SELECT ename || ‘ , ‘ || job FROM emp;

OUTPUT:
ENAME||','||JOB
----------------------
SMITH , CLERK
ALLEN , SALESMAN
WARD , SALESMAN
JONES , MANAGER
MARTIN , SALESMAN
BLAKE , MANAGER
CLARK , MANAGER
SCOTT , ANALYST
KING , PRESIDENT
TURNER , SALESMAN
ADAMS , CLERK
JAMES , CLERK
FORD , ANALYST
MILLER , CLERK

ANALYSIS:

Combines both name and designation as a single string separated by,


Logical Operators

AND, OR and NOT are the logical operators used in SQL.

INPUT:

SQL> SELECT ename FROM emp WHERE ename LIKE ‘%A%’ AND ename NOT LIKE ‘%A%A%’

OUTPUT:

ENAME

----------
ALLEN
WARD

MARTIN
BLAKE

CLARK

JAMES

ANALYSIS:

Displays all the employees whose names contains letter A exactly one time.

SELECT * FROM emp WHERE sal >= 3000 AND sal <= 4000;

SELECT * FROM emp WHERE sal BETWEEN 3000 AND 4000;

SELECT * FROM emp WHERE sal NOT BETWEEN 3000 AND 4000;

Miscellaneous Operators: IN, BETWEEN and DISTINCT

The two operators IN and BETWEEN provide shorthand for functions you already know how to do.
You could type the following:

INPUT:
SQL> SELECT ename, job FROM emp WHERE job='CLERK' OR job=‘MANAGER’ OR job='SALESMAN';

OUTPUT:
ENAME JOB
---------- ---------
SMITH CLERK
ALLEN SALESMAN
WARD SALESMAN
JONES MANAGER
MARTIN SALESMAN
BLAKE MANAGER
CLARK MANAGER
TURNER SALESMAN
ADAMS CLERK
JAMES CLERK
MILLER CLERK

ANALYSIS:

Display employees with designations manager, clerk, and salesman,

The above statement takes more time to parse it, which reduces the efficiency.
INPUT:
SQL> SELECT ename,job FROM emp WHERE job IN('CLERK','SALESMAN','MANAGER');

OUTPUT:
ENAME JOB
---------- ---------
SMITH CLERK
ALLEN SALESMAN
WARD SALESMAN
JONES MANAGER
MARTIN SALESMAN
BLAKE MANAGER
CLARK MANAGER
TURNER SALESMAN
ADAMS CLERK
JAMES CLERK
MILLER CLERK

ANALYSIS:

Display employees with designations manager, clerk, and salesman,

INPUT:
SQL> SELECT ename, job FROM emp WHERE job NOT IN('CLERK','SALESMAN','MANAGER');

OUTPUT:
ENAME JOB
---------- ---------
SCOTT ANALYST
KING PRESIDENT
FORD ANALYST

ANALYSIS:

Display designations other than manager, clerk, and salesman

INPUT:
SQL> SELECT ename,hiredate FROM emp WHERE hiredate IN (‘01-MAY-1981’,’09-DEC-1982’);

OUTPUT:
ENAME HIREDATE
---------- ---------
BLAKE 01-MAY-81
SCOTT 09-DEC-82

ANALYSIS:

Display employees who joined on two different dates.


Distinct Operator

INPUT:
SQL> SELECT DISTINCT job FROM emp;

OUTPUT:
JOB
---------
ANALYST
CLERK
MANAGER
PRESIDENT
SALESMAN

ANALYSIS:
Distinct operator displays unique designations. Distinct operator by default
displays the information in ascending order.

ORDER BY CLAUSE

Display the information in a particular order (Ascending or descending order)

Syntax: SELECT <COLUMNS> FROM <TABLE> WHERE <CONDITION> ORDER BY <COLUMN(S)>;

INPUT:
SQL> SELECT ename FROM emp ORDER BY ename;

OUTPUT:
ENAME
----------
ADAMS
ALLEN
BLAKE
CLARK
FORD
JAMES
JONES
KING
MARTIN
MILLER
SCOTT
SMITH
TURNER
WARD

ANALYSIS:

Display employees in ascending order of names.


Ordering on multiple columns is also available as shown below.

INPUT:
SQL> SELECT job,ename,sal FROM emp ORDER BY job,ename;

OUTPUT:
JOB ENAME SAL
------- ----------
-- ----------
ANALYST FORD 3000
ANALYST SCOTT 3000
CLERK ADAMS 1100
CLERK JAMES 950
CLERK MILLER 1300
CLERK SMITH 800
MANAGER BLAKE 2850
MANAGER CLARK 2450
MANAGER JONES 2975
PRESIDE
NT KING 5000
SALESMA
N ALLEN 1600
SALESMA
N MARTIN 1250
SALESMA
N TURNER 1500
SALESMA
N WARD 1250

ANALYSIS:

Display employees in ascending order of jobs. With each job it places the
information in ascending order of names.

INPUT:
SQL> SELECT * FROM emp ORDER BY job, ename desc;

ANALYSIS:
Display employees in ascending order by jobs. With each job it places the
information in descending order of names.

INPUT:
SQL> SELECT * FROM emp ORDER BY job desc, ename DESC;

ANALYSIS:
Display employees in descending order by jobs. With each job it places the information
in descending order of names.

INPUT:
SQL> SELECT * FROM emp WHERE job != ‘CLERK’ ORDER BY job;

OUTPUT:
Display employees in ascending order of jobs other than clerks.

ANALYSIS:
When we are executing the query, it is divided into two different parts.

1) SELECT * FROM emp WHERE job != ‘CLERK’


2) ORDER BY job;
First part is going to execute first, and selects all the employees whose
designation is other than clerk and places them in a temporary table.
On the temporary table, order by clause is applied, places the information in
ascending order by jobs in the shadow page, from where end user can able to see
the output.

We can also use order by clause as

INPUT:
SQL> SELECT * FROM EMP ORDER BY 3;

ANALYSIS:
It places the information in the order of third column in the table.
FUNCTIONS

A function is a sub program, which executes whenever we call it and returns a value to the calling place.
Oracle has a large collection of predefined functions. Each function has a name and some parameters on
which the function will work and return some answer.

These functions are classified into two types

Predefined functions

 User defined functions

Predefined functions

These functions are again classified into two types

Group or Aggregate Functions


Single row Functions
Now let us has some detailed description of each of these functions, their use and application.

While describing about these functions, we have used a notation < expr>
expr means expression that is to be passed as a parameter.
Depending on the function you are using expression can be one of
A Column Name
A Column Name used with a function
A Sub-query
An equation formed using one or more columns
Aggregate Functions

These functions are also referred to as group functions. They return a value based on the non-null values
in a column.

COUNT([DISTINCT] <expr>)

The function COUNT returns the number of rows that satisfy the condition in the WHERE clause.

Say you wanted to know how many employees are there.

INPUT:
SQL> SELECT COUNT(*) FROM emp;

OUTPUT:

COUNT(*)
--------
14

ANALYSIS:
It counts the number of rows in that table.

To make the code more readable, try an alias:

INPUT:
SQL> SELECT COUNT(*) NUM_OF_EMP FROM emp;

OUTPUT:
NUM_OF_EMP
-------------------
14

INPUT:
SQL> SELECT COUNT(comm) FROM emp;

OUTPUT:
COUNT(comm)
--------
4

ANALYSIS:
It counts only those when there is a value in comm Column
Note: Count (*) faster than count(comm) Count(*) count the row when a row present in
the table where as Count(comm) counts the row only when there is a value in the column.

INPUT:
SQL> SELECT COUNT(*) FROM emp WHERE job = ‘MANAGER’;

OUTPUT:
COUNT(*)
-------
4

ANALYSIS:
It counts only managers

INPUT:
SQL> SELECT COUNT(DISTINCT job) FROM emp;

OUTPUT:
COUNT (*)
-------
4

ANALYSIS:

It counts only distinct jobs that means filter duplicates.


SUM(<expr>)

SUM does just that. It returns the sum of all values in a column selected by the select command.

INPUT:
SQL> SELECT SUM(sal) TOTAL_SALARY FROM emp;

OUTPUT:
TOTAL_SALARY
-------------
29025

ANALYSIS:
Find the total salary drawn by all the employees

INPUT:
SQL> SELECT SUM(sal) TOTAL_SALARY, SUM(comm) TOTAL_COMM FROM emp;

OUTPUT:
TOTAL_SALARY TOTAL_COMM
------------- ----------
29025 2200

ANALYSIS:

The totals of sal column and the comm column are calculated and displayed

INPUT:
SQL> SELECT SUM(sal) TOTAL_SALARY,SUM(comm) TOTAL_COMM FROM emp WHERE job=„SALESMAN’;

OUTPUT:
TOTAL_SALARY TOTAL_COMM
------------- ----------

5600 2200
AVG(<expr>)

The AVG function computes the average of a column.

INPUT:
SQL> SELECT AVG(sal) AVERAGE_SALARY FROM emp;

OUTPUT:
AVERAGE_SALARY
---------------
2073.21429

ANALYSIS:
Find the average salary of all the employees

INPUT:
SQL> SELECT AVG(comm) AVERAGE_COMM FROM emp;

OUTPUT:
AVERAGE_COMM
------------
550

ANALYSIS:

Functions ignores null rows


MAX(<expr>)

Returns the Maximum value in the given column of values

INPUT:
SQL> SELECT MAX(sal) FROM emp;

OUTPUT:
MAX(SAL)
--------
5000

ANALYSIS:
Takes the value from one different rows from one particular column

INPUT:
SQL> SELECT MAX(ename) FROM emp;

OUTPUT:
MAX(ENAME)
--------
WARD

ANALYSIS:
Max of name is identified based on ASCII value when a char column is given

INPUT:

SQL> SELECT MAX (hiredate) FROM emp;

OUTPUT:

MAX(HIREDATE)
-------------

12-JAN-83

ANALYSIS:

Can find the maximum date in the given column


MIN(<expr>)

Finds the minimum value in the given column of values. This example shows the use of min function with
a numeric column.

INPUT:
SQL> SELECT MIN(sal) FROM emp;

OUTPUT:
MIN(SAL)
--------
800

Using min with char column

INPUT:
SQL> SELECT MIN(ename) FROM emp;

OUTPUT:
MIN (ENAME)
--------

ADAMS

The following example shows the use of all aggregate functions together.

INPUT:
SQL> SELECT SUM(sal),AVG(sal),MIN(sal),MAX(sal),COUNT(*) FROM emp;

OUTPUT:
SUM(SAL MIN(SAL COUNT(
) AVG(SAL) ) MAX(SAL) *)
------- ------- -----
-- --------- - -------- ---
2073.2142
29025 9 800 5000 14

ANALYSIS:

All the aggregate functions can be used together in a single SQL statement
SINGLE ROW FUNCTIONS

These functions work on each and every row and return a value to the calling places.

These functions are classified into different types

Arithmetic Functions
 Character Functions

 Date functions

 Miscellaneous Functions

Arithmetic Functions

Many of the uses you have for the data you retrieve involve mathematics. Most Implementations of SQL
provide arithmetic functions similar to that of operators covered here.

ABS(<expr>)

The ABS function returns the absolute value of the number you point to. For example:

INPUT:
SQL> SELECT ABS(-10) ABSOLUTE_VALUE;

OUTPUT:
ABSOLUTE_VALUE
---------------
10
ANALYSIS:
ABS changes all the negative numbers to positive and leaves positive numbers alone.

Dual is a system table or dummy table from where we can display system information
(i.e. system date and username etc) or we can make our own calculations.
CEIL(<expr>) and FLOOR(<expr>)

CEIL returns the smallest integer greater than or equal to its argument. FLOOR does just the
reverse, returning the largest integer equal to or less than its argument.

INPUT:
SQL> SELECT CEIL(12.145);

OUTPUT:
CEIL(12.145)
------------

13

INPUT:
SQL> SELECT CEIL(12.000);

OUTPUT:
CEIL(12.000)
-----------
12
ANALYSIS:

Minimum we require one decimal place, to get the next higher integer number

INPUT:
SQL> SELECT FLOOR(12.678) ;

OUTPUT:
FLOOR(12.678)
-----------------

12

INPUT:
SQL> SELECT FLOOR(12.000) ;

OUTPUT:
FLOOR(12.000)
-----------------

12

SQRT(<expr>)

The function SQRT returns the square root of an argument. Because the square root of a negative
number is undefined, you cannot use SQRT on negative numbers.

INPUT:
SQL> SELECT SQRT(4) ;

OUTPUT:
SQRT(4)
---------
2
MOD(<expr1>,<expr2>)

It returns remainder when we divide one value with another value

INPUT:
SQL> SELECT MOD(5,2) ;

OUTPUT:
MOD(5,2)
----------
1

INPUT:
SQL> SELECT MOD(2,5) ;

OUTPUT:
MOD(2,5)
----------
2
ANALYSIS:
When numerator value less than denominator, it returns numerator value as remainder.

POWER(<expr1>,<expr2>)

To raise one number to the power of another, use POWER. In this function the first argument is raised to
the power of the second:

INPUT:
SQL> SELECT POWER(5,3) ;

OUTPUT:
POWER(5,3)
----------
125

SIGN(<expr>)

SIGN returns -1 if its argument is less than 0, 0 if its argument is equal to 0, and 1 if its
argument is greater than 0,

INPUT:
SQL> SELECT SIGN(-10), SIGN(10),SIGN(0) ;

OUTPUT:
SIGN(-10) SIGN(10) SIGN(0)
---------- ---------- ----------
-1 1 0
CHARACTER FUNCTIONS

Many implementations of SQL provide functions to manipulate characters and strings of characters.

CHR(<expr>)

CHR returns the character equivalent of the number it uses as an argument. The character it returns
depends on the character set of the database. For this example the database is set to ASCII.

INPUT:
SQL> SELECT CHR(65) ;

OUTPUT:
CHR(65)
-------

CONCAT(<expr1>,<expr2>)

It is similar to that of concatenate operator ( | | )

INPUT:
SQL> SELECT CONCAT(‘KRISHNA’,’KANTH’) ;

OUTPUT:
CONCAT(‘KRISHNA’, ‘KANTH’)
---------------------------

KRISHNA KANTH

INITCAP(<expr>)

INITCAP capitalizes the first letter of a word and makes all other characters lowercase.

INPUT:
SQL> SELECT ename ‘BEFORE’,INITCAP(ename) ‘AFTER’ FROM emp;

OUTPUT:
BEFORE AFTER
---------- ----------
SMITH Smith
ALLEN Allen
WARD Ward
JONES Jones
MARTIN Martin
BLAKE Blake
CLARK Clark
SCOTT Scott
KING King
TURNER Turner
ADAMS Adams
JAMES James
FORD Ford
MILLER Miller
ANALYSIS:

Observe that the first letter of every word is capital and remaining smalls.
LOWER(<expr>) and UPPER(<expr>)

As you might expect, LOWER changes all the characters to lowercase; UPPER does just the changes all
the characters to uppercase.

INPUT:
SQL>SELECT ename,UPPER(ename) UPPER_CASE,LOWER(ename) LOWER_CASE FROM emp;

OUTPUT:
ENAME UPPER_CASE LOWER_CASE
--------
-- ---------- ----------
SMITH SMITH smith
ALLEN ALLEN allen
WARD WARD ward
JONES JONES jones
MARTIN MARTIN martin
BLAKE BLAKE blake
CLARK CLARK clark
SCOTT SCOTT scott
KING KING king
TURNER TURNER turner
ADAMS ADAMS adams
JAMES JAMES james
FORD FORD ford
MILLER MILLER miller

LPAD(expr1,expr2[,expr3]) and RPAD(expr1,expr2[,expr3])

LPAD and RPAD take a minimum of two and a maximum of three arguments. The first argument is
the character string to be operated on. The second is the number of characters to pad it with, and the
optional third argument is the character to pad it with. The third argument defaults to a blank, or it can
be a single character or a character string.

The following statement adds five pad characters, assuming that the field LASTNAME is defined as a
15-character field:

INPUT:
SQL> SELECT LPAD(ename,15,’*’) FROM emp;

OUTPUT:
LPAD(ENAME,15,'
---------------
**********SMITH
**********ALLEN
***********WARD
**********JONES
*********MARTIN
**********BLAKE
**********CLARK
**********SCOTT
***********KING
*********TURNER
**********ADAMS
**********JAMES
***********FORD
*********MILLER

ANALYSIS:
15 locations allocated to display ename, out of that, name is occupying some space
and in the remaining space to the left side of the name pads with *.
INPUT:
SQL> SELECT RPAD(5000,10,’*’) ;

OUTPUT:
RPAD(5000,10,’*’)
--------------------

5000******

LTRIM(expr1[,expr2]) and RTRIM(expr1[,expr2])

LTRIM and RTRIM take at least one and at most two arguments. The first argument, like LPAD and RPAD,
is a character string. The optional second element is either a character or character string or defaults to a
blank. If you use a second argument that is not a blank, these trim functions will trim that character the
same way they trim the blanks in the following examples.

INPUT:
SQL> SELECT ename, RTRIM(ename,’R’) FROM emp;

OUTPUT:
ENAME RTRIM(ENAM
---------- ----------
SMITH SMITH
ALLEN ALLEN
WARD WARD
JONES JONES
MARTIN MARTIN
BLAKE BLAKE
CLARK CLARK
SCOTT SCOTT
KING KING
TURNER TURNE
ADAMS ADAMS
JAMES JAMES
FORD FORD
MILLER MILLE

ANALYSIS:

Removes the rightmost character

Trim(expr)

This functions removes either leading or trailing or both specified characters in the given string

INPUT:
SQL> SELECT TRIM(‘H’ from ‘Hello friend’) ;

OUTPUT:
ello friends

ANALYSIS:
Removed the left side H in the string
REPLACE(expr1,expr2,expr3)

REPLACE does just that. Of its three arguments, the first is the string to be searched. The second is the
search key. The last is the optional replacement string. If the third argument is left out or NULL, each
occurrence of the search key on the string to be searched is removed and is not replaced with anything.

INPUT:
SQL> SELECT REPLACE (‘RAMANA’,’MA’, VI’) ;

OUTPUT:
REPLACE (‘RAMANA’,’MA’, ‘VI’)
----------------------------
RAVINA

INPUT:
SQL> SELECT REPLACE(‘RAMANA’,’MA’) ;

OUTPUT:
REPLACE(„RAMANA’,’MA’)
----------------------
RANA

ANALYSIS:

When the replace string is missing, search string removed from the given string

INPUT:
SQL> SELECT REPLACE (‘RAMANA’,’MA’, NULL) ;

OUTPUT:
REPLACE („RAMANA’,’MA’, NULL)
------------------------------

RANA

TRANSLATE(expr1,expr2,expr3)

The function TRANSLATE takes three arguments: the target string, the FROM string, and the TO string.
Elements of the target string that occur in the FROM string are translated to the corresponding element
in the TO string.

INPUT:
SQL> SELECT TRANSLATE(‘RAMANA’,’MA’,’CD’) ;

OUTPUT:
TRANSLATE(‘RAMANA’,’MA’,’CD’)
-----------------------------
RDCDND

ANALYSIS:
Notice that the function is case sensitive. When search string matches, it replaces
with corresponding replace string and if any one character is matching in the search
string, it replaces with corresponding replace character.
SUBSTR(expr1,expr2[,expr3])

This three-argument function enables you to take a piece out of a target string. The first argument is the
target string. The second argument is the position of the first character to be output. The third argument
is the number of characters to show.

INPUT:
SQL> SELECT SUBSTR(‘RAMANA’,1,3) ;

OUTPUT:
SUBSTR(‘RAMANA’,1,3)
--------------------
RAM

ANALYSIS:
It takes first 3 characters from first character

INPUT:
SQL> SELECT SUBSTR(‘RAMANA’,3,3) ;

OUTPUT:
SUBSTR(‘RAMANA’,3,3)
--------------------
MAN

ANALYSIS:

It takes 3 characters from third position

INPUT:
SQL> SELECT SUBSTR(‘RAMANA’,-2,2) ;

OUTPUT:
SUBSTR(‘RAMANA’,-2,2)
---------------------
NA

ANALYSIS:
You use a negative number as the second argument, the starting point is determined by
counting backwards from the right end.

INPUT:
SQL> SELECT SUBSTR(‘RAMANA’,1,2) || SUBSTR(‘RAMANA’,-2,2) ;

OUTPUT:
SUBSTR(„RAMANA
--------------
RANA

ANALYSIS:
First two characters and last two characters are combined together as a single string
INPUT:
SQL> SELECT SUBSTR(‘RAMANA’,3) ;

OUTPUT:
SUBSTR(‘RAMANA’,3)
------------------
MANA

ANALYSIS:

When third argument is missing, it takes all the character from starting position

INPUT:
SQL> SELECT * FROM emp WHERE SUBSTR(hiredate,4,3) = SUBSTR(SYSDATE,4,3);

ANALYSIS:
Displays all the employees who joined in the current month SYSDATE is a single row
function, which gives the current date.

INPUT:
SQL> SELECT SUBSTR(‘RAMANA’,1,2) || SUBSTR(‘RAMANA’,-2,2) ;

OUTPUT:
SUBSTR(‘RAMANA’,1,2)
--------------------
RANA

ANALYSIS:

First two characters and Last two characters are combined together as a single string
INSTR(expr1,expr2[,expr3[,expr4]])

To find out where in a string a particular pattern occurs, use INSTR. Its first argument is the target
string. The second argument is the pattern to match. The third and forth are numbers representing
where to start looking and which match to report.

This example returns a number representing the first occurrence of O starting with the second

INPUT:
SQL> SELECT INSTR(‘RAMANA’,’A’) ;

OUTPUT:
INSTR(„RAMANA’,’A’)
-------------------
2
ANALYSIS:

Find the position of the first occurrence of letter A

INPUT:
SQL> SELECT INSTR(‘RAMANA’,’A’,1,2) ;

OUTPUT:
INSTR(„RAMANA’,’A’,1,2)
-----------------------
4

ANALYSIS:
Find the position of the second occurrence of letter A from the beginning of the
string. Third argument represents from which position, Fourth argument represents,
which occurrence.

INPUT:
SQL> SELECT INSTR(‘RAMANA’,’a’) ;

OUTPUT:
INSTR(„RAMANA’,’a’)
-------------------
0
ANALYSIS:
Function is case sensitive; it returns 0 (zero) when the given character is not found.
INPUT:

SQL> SELECT INSTR(‘RAMANA’,’A’,3,2) ;

OUTPUT:

INSTR(„RAMANA’,’A’,3,2)
----------------------

ANALYSIS:

Find the position of the second occurrence of letter A from 3rd position of the string
CASE

INPUT:

SQL> SELECT job,


CASE job
WHEN 'MANAGER' then 'VP'

WHEN 'CLERK' THEN 'EXEC'


WHEN 'SALESMAN' THEN 'S.OFFICER'
ELSE

job
END
FROM emp;

OUTPUT:
JOB CASEJOBWH
--------- ---------
CLERK EXEC
SALESMAN S.OFFICER
SALESMAN S.OFFICER
MANAGER VP
SALESMAN S.OFFICER
MANAGER VP
MANAGER VP
ANALYST ANALYST
PRESIDENT PRESIDENT
SALESMAN S.OFFICER
CLERK EXEC
CLERK EXEC
ANALYST ANALYST
CLERK EXEC

ANALYSIS:
Works similar to that of DECODE
LENGTH(expr)

Finds the length of the given information

SQL> SELECT ename,LENGTH(ename)FROM emp;

SQL> SELECT sal,LENGTH(sal) FROM emp;

ASCII(expr)

Finds the ASCII value of the given character

SQL> SELECT ASCII(‘A’) ;

CAST(expr)

Converts one type of information into another type

SQL> SELECT 50 NUMB, CAST(50 as VARCHAR(2)) VALUE ;


GROUP BY clause with SELECT statement

Syntax: SELECT [column,] group_function(column)...


FROM table
[WHERE condition]

[GROUP BY group_by_expression]
[HAVING having_expression]
[ORDER BY column];

Group by statement groups all the rows with the same column value. Use to generate summary
output from the available data. Whenever we use a group function in the SQL statement, we have to
use a group by clause.

INPUT:
SQL> SELECT job, COUNT (*) FROM emp GROUP BY job;

OUTPUT:
JOB COUNT(*)
--------- ----------
ANALYST 2
CLERK 4
MANAGER 3

PRESIDENT 1
SALESMAN 4

ANALYSIS:
Counts number of employees under each and every job. When we are grouping on job,
initially jobs are placed in ascending order in a temporary segment. On the temporary
segment, group by clause is applied, so that on each similar job count function
applied.

INPUT:
SQL> SELECT job, SUM(sal) FROM emp GROUP BY job;

OUTPUT:
JOB SUM(SAL)
--------- ----------
ANALYST 6000
CLERK 4150
MANAGER 8275
PRESIDENT 5000
SALESMAN 5600

ANALYSIS:

With each job, it finds the total salary


ERROR with GROUP BY Clause

Note :

Only grouped columns allowed in the group by clause


 Whenever we are using a group function in the SQL statement, we have to use group by
clause.
INPUT:
SQL> SELECT job,COUNT(*) FROM emp;

OUTPUT:
SELECT job, COUNT (*) FROM emp
*
ERROR at line 1:
ORA-00937: not a single-group group function

ANALYSIS:
This result occurs because the group functions, such as SUM and COUNT, are designated
to tell you something about a group or rows, not the individual rows of the table. This
error is avoided by using JOB in the group by clause, which forces the COUNT to count
all the rows grouped within each job.

INPUT:
SQL> SELECT job,ename,COUNT(*) FROM emp GROUP BY job;

OUTPUT:
SELECT JOB,ENAME,COUNT(*) FROM EMP GROUP BY JOB
*
ERROR at line 1:
ORA-00979: not a GROUP BY expression

ANALYSIS:
In the above query, JOB is only the grouped column where as ENAME column is not a
grouped column. Whatever the columns we are grouping, the same column is allowed to
display.

INPUT:
SQL> SELECT job, MIN(sal),MAX(sal) FROM emp GROUP BY job;

OUTPUT:
MAX(SAL
JOB MIN(SAL) )
------- ----------
-- ----------
ANALYST 3000 3000
CLERK 800 1300
MANAGER 2450 2975
PRESIDE
NT 5000 5000
SALESMA
N 1250 1600

ANALYSIS:

With each job, it finds the MINIMUM AND MAXIMUM SALARY


For displaying Total summary information from the table.

INPUT:
SQL> SELECT job, SUM(sal),AVG(sal),MIN(sal),MAX(sal) ,COUNT(*) FROM emp GROUP BY job;

OUTPUT:
COUNT(*
JOB SUM(SAL) AVG(SAL) MIN(SAL) MAX(SAL) )
------- ---------- ---------- ---------- ----------
-- ----------
ANALYST 6000 3000 3000 3000 2
CLERK 4150 1037.5 800 1300 4
2758.3333
MANAGER 8275 3 2450 2975 3
PRESIDE
NT 5000 5000 5000 5000 1
SALESMA
N 5600 1400 1250 1600 4

ANALYSIS:

With each job, finds the total summary information.

To display the output Designation wise, Department wise total salaries With a matrix style report.

INPUT:
SQL> SELECT deptno,job,COUNT(*) FROM emp GROUP BY deptno,job;

OUTPUT:
COUNT(*
DEPTNO JOB )
-------- ---------
-- ----------
10 CLERK 1
10 MANAGER 1
PRESIDEN
10 T 1
20 CLERK 2
20 ANALYST 2
20 MANAGER 1
30 CLERK 1
30 MANAGER 1
30 SALESMAN 4

ANALYSIS:

Department wise, Designation wise , counts the number of employees

HAVING CLAUSE

Whenever we are using a group function in the condition, we have to use having clause. Having clause is
used along with group by clause.

For example, to display Designation wise total salaries

INPUT:
SQL> SELECT job,SUM(sal) FROM emp GROUP BY job;

OUTPUT:
JOB SUM(SAL)
--------- ----------

ANALYST 6000
CLERK 4150
MANAGER 8275

PRESIDENT 5000
SALESMAN 5600

SQL> SPOOL OFF

To Display only those designations, whose total salary is more than 5000

INPUT:
SQL> SELECT job,SUM(sal) FROM emp WHERE SUM(sal) > 5000 GROUP BY job;

OUTPUT:
SELECT JOB,SUM(SAL) FROM EMP WHERE SUM(SAL) > 5000 GROUP BY JOB
*
ERROR at line 1:
ORA-00934: group function is not allowed here

ANALYSIS:
Where clause doesn’t allow using group function in the condition.

When we are using group function in the condition, we have to use having clause.

INPUT:
SQL> SELECT job,SUM(sal) FROM emp GROUP BY job HAVING SUM(sal) > 5000;

OUTPUT:
JOB SUM(SAL)
--------- ----------
ANALYST 6000
MANAGER 8275
SALESMAN 5600

ANALYSIS:

Displays all the designations whose total salary is more than 5000.
INPUT:
SQL> SELECT job,COUNT(*) FROM emp GROUP BY job HAVING COUNT(*) BETWEEN 3 AND 5;

OUTPUT:
JOB COUNT(*)
--------- ----------
CLERK 4
MANAGER 3
SALESMAN 4

ANALYSIS:

Displays all the designations whose number where employees between 3 and 5

INPUT:
SQL> SELECT sal FROM emp GROUP BY sal HAVING COUNT(sal) > 1;

OUTPUT:
SAL
----------
1250
3000

ANALYSIS:

Displays all the salaries, which are appearing more than one time in the table.

POINTS TO REMEMBER

WHERE clause can be used to check for conditions based on values of columns and expressions
but not the result of GROUP functions.

HAVING clause is specially designed to evaluate the conditions that are based on group
functions such as SUM, COUNT etc.
HAVING clause can be used only when GROUP BY clause is used.

ORDER OF EXECUTION

Here are the rules ORCALE uses to execute different clauses given in SELECT command

Selects rows based on Where clause


 Groups rows based on GROUP BY clause

 Calculates results for each group

 Eliminate groups based on HAVING clause

 Then ORDER BY is used to order the results

INPUT:
SQL> 0.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy