Get Back in Control of your SQL
SQL and Java could work
together so much better if
we only let them.

Copyright (c) 2009-2013 by Data Geekery GmbH.
Intro

SQL and Java

jOOQ

Examples

About me

Java, SQL, PL/SQL
2001-2006 MSc Computer Science EPFL
2006-2009 Ergon Informatik AG, Zürich
2009-2013 Crealogix E-Banking AG, Zürich
2013 Adobe Systems Inc, Basel
2013
Data Geekery GmbH, Zürich
Copyright (c) 2009-2013 by Data Geekery GmbH.
Intro

SQL and Java

About my motivation

SQL dominates database systems
SQL seems «low level» and «dusty»
SQL can do so much more
SQL should be «sexy» again

Copyright (c) 2009-2013 by Data Geekery GmbH.

jOOQ

Examples
Intro

About today

History of SQL in Java
Persistence in Java today
jOOQ
jOOQ Examples

Copyright (c) 2009-2013 by Data Geekery GmbH.

SQL and Java

jOOQ

Examples
Intro

SQL and Java

jOOQ

SQL and Java - never ending story

JDBC
EJB 2.0 with EntityBeans
Hibernate / TopLink
EJB 3.0 with JPA 2.x
iBATIS / JDO / SpringData / 1’000 others

Copyright (c) 2009-2013 by Data Geekery GmbH.

Examples
Intro

SQL and Java

jOOQ

JDBC

PreparedStatement stmt = connection.prepareStatement(
"SELECT text FROM products WHERE cust_id = ? AND value < ?");
stmt.setInt(1, custID);
stmt.setBigDecimal(2, BigDecimal.ZERO);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
System.out.println(rs.getString("TEXT"));
}

Copyright (c) 2009-2013 by Data Geekery GmbH.

Examples
Intro

SQL and Java

JDBC – the naked truth

01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:

PreparedStatement stmt = connection.prepareStatement(
"SELECT p.text txt" +
(isAccount ? ", NVL(a.type, ?) " : "") +
"FROM products p " +
(isAccount ? " INNER JOIN accounts a USING (prod_id) " : "") +
" WHERE p.cust_id = ? AND p.value < ?" +
(isAccount ? " AND a.type LIKE '%" + type + "%'" : "");
stmt.setInt(1, defaultType);
stmt.setInt(2, custID);
stmt.setBigDecimal(3, BigDecimal.ZERO);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
Clob clob = rs.getClob("TEXT");
System.out.println(clob.getSubString(1, (int) clob.length());
}
rs.close();
stmt.close();

Copyright (c) 2009-2013 by Data Geekery GmbH.

jOOQ

Examples
Intro

SQL and Java

jOOQ

Examples

JDBC – the naked truth

01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:

PreparedStatement stmt = connection.prepareStatement(
//
"SELECT p.text txt" +
//
(isAccount ? ", NVL(a.type, ?) " : "") +
//
"FROM products p " +
// Syntax error when isAccount == false
(isAccount ? " INNER JOIN accounts a USING (prod_id) " : "") + //
" WHERE p.cust_id = ? AND p.value < ?" +
//
(isAccount ? " AND a.type LIKE '%" + type + "%'" : "");
// Syntax error and SQL injection possible
stmt.setInt(1, defaultType);
// Wrong bind index
stmt.setInt(2, custID);
//
stmt.setBigDecimal(3, BigDecimal.ZERO);
//
ResultSet rs = stmt.executeQuery();
//
while (rs.next()) {
Clob clob = rs.getClob("TEXT");
System.out.println(clob.getSubString(1, (int) clob.length());
}

//
// ojdbc6: clob.free() should be called
//
//

rs.close();
stmt.close();

// close() not really in finally block
//

Copyright (c) 2009-2013 by Data Geekery GmbH.
Intro

SQL and Java

jOOQ

Examples

JDBC – pros and cons

JDBC Pros
No restrictions (procedures, UDTs, vendor-specific features)
Simple
Fast

JDBC Cons
String-based
No syntax checking
Lots of code, flat / indexed variables
Repetitive
Vendor lock-in
Copyright (c) 2009-2013 by Data Geekery GmbH.
Intro

SQL and Java

EJB 2.0 EntityBeans

public interface CustomerRequest extends EJBObject {
BigInteger getId();
String getText();
void setText(String text);
@Override
void remove();
}
public interface CustomerRequestHome extends EJBHome {
CustomerRequest create(BigInteger id);
CustomerRequest find(BigInteger id);
}

Copyright (c) 2009-2013 by Data Geekery GmbH.

jOOQ

Examples
Intro

EJB 2.0 – the naked truth

<weblogic-enterprise-bean>
<ejb-name>com.example.CustomerRequestHome</ejb-name>
<entity-descriptor>
<pool>
<max-beans-in-free-pool>100</max-beans-in-free-pool>
</pool>
<entity-cache>
<max-beans-in-cache>500</max-beans-in-cache>
<idle-timeout-seconds>10</idle-timeout-seconds>
<concurrency-strategy>Database</concurrency-strategy>
</entity-cache>
<persistence>
<delay-updates-until-end-of-tx>True</delay-updates-until-end-of-tx>
</persistence>
<entity-clustering>
<home-is-clusterable>False</home-is-clusterable>
<home-load-algorithm>round-robin</home-load-algorithm>
</entity-clustering>
</entity-descriptor>
<transaction-descriptor/>
<enable-call-by-reference>True</enable-call-by-reference>
<jndi-name>com.example.CustomerRequestHome</jndi-name>
</weblogic-enterprise-bean>

Copyright (c) 2009-2013 by Data Geekery GmbH.

SQL and Java

jOOQ

Examples
Intro

SQL and Java

jOOQ

EJB 2.0 – pros and cons

EJB 2.0 Pros
Intuitive client code (create(), remove(), store())
Powerful (transactions, caching, etc.)

EJB 2.0 Cons
Not intuitive implementation (Home, conventions)
Lots of configuration
XDoclet
Checked Exceptions (FinderException, CreateException)
Repetitive (except with a code generator)
Domain Model depends on container
Copyright (c) 2009-2013 by Data Geekery GmbH.

Examples
Intro

SQL and Java

Hibernate – ORM

Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(new Event("Conference", new Date());
session.save(new Event("After Party", new Date());
List result = session.createQuery("from Event").list();
for (Event event : (List<Event>) result) {
System.out.println("Event : " + event.getTitle());
}
session.getTransaction().commit();
session.close();

Copyright (c) 2009-2013 by Data Geekery GmbH.

jOOQ

Examples
Intro

SQL and Java

Hibernate – «navigation»

List result = session.createQuery("from Event").list();
for (Event event : (List<Event>) result) {
System.out.println("Participants of " + event);
for (Person person : event.getParticipants()) {
Company company = person.getCompany();
System.out.println(person + " (" + company + ")");

}
}

Copyright (c) 2009-2013 by Data Geekery GmbH.

jOOQ

Examples
Intro

SQL and Java

jOOQ

Hibernate – the naked truth

<hibernate-mapping package="org.hibernate.tutorial.hbm">
<class name="Event" table="EVENTS">
<id name="id" column="EVENT_ID">
<generator class="increment"/>
</id>
<property name="date" type="timestamp" column="EVENT_DATE"/>
<property name="title"/>
<set name="participants" inverse="true">
<key column="eventId"/>
<one-to-many entity-name="Person"/>
</set>
</class>
</hibernate-mapping>

Copyright (c) 2009-2013 by Data Geekery GmbH.

Examples
Intro

Hibernate – pros and cons

Hibernate Pros
Very intuitive client code (POJOs)
POJO code generator
Objects can be «navigated»
Hibernate implements JPA

Hibernate Cons
Hard to configure
Caching is complex
HQL is limited. SQL can do more.
ORM impedance mismatch
Copyright (c) 2009-2013 by Data Geekery GmbH.

SQL and Java

jOOQ

Examples
Intro

SQL and Java

jOOQ

JPA and EJB 3.0

EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
em.persist(new Event("Conference", new Date());
em.persist(new Event("After Party", new Date());
List result = em.createQuery("from Event").getResultList();
for (Event event : (List<Event>) result) {
System.out.println("Event : " + event.getTitle());
}
em.getTransaction().commit();
em.close();

Copyright (c) 2009-2013 by Data Geekery GmbH.

Examples
Intro

SQL and Java

jOOQ

EJB 3.0 – the naked truth

@Entity @Table(name = "EVENTS")
public class Event {
private Long id;
private String title;
private Date date;
@Id @GeneratedValue(generator = "increment")
@GenericGenerator(name = "increment", strategy = "increment")
public Long getId() { /* … */ }
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "EVENT_DATE")
public Date getDate() { /* … */ }

Copyright (c) 2009-2013 by Data Geekery GmbH.

Examples
Intro

SQL and Java

jOOQ

Examples

Criteria – the naked truth

EntityManager em= ...
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Person> criteria = builder.createQuery(Person.class);
Root<Person> person = criteria.from(Person.class);
Predicate condition = builder.gt(person.get(Person_.age), 20);
criteria.where(condition);
TypedQuery<Person> query = em.createQuery(query);
List<Person> result = query.getResultList();

Copyright (c) 2009-2013 by Data Geekery GmbH.
Intro

SQL and Java

jOOQ

JPA – pros and cons

JPA Facts
Hibernate HQL => JPQL
Hibernate XML mapping => annotations
Hibernate Sessions => EntityManager

JPA Pros
Next standard after EJB 2.0
Good implementations, such as Hibernate, EclipseLink

JPA Cons
CriteriaQuery
Copyright (c) 2009-2013 by Data Geekery GmbH.

Examples
Intro

SQL and Java

jOOQ

What else is there?

iBATIS / MyBatis
XML based. SQL is externalised
Active, but seems to be at the end of its hype cycle

JDO
Has JDOQL (similar to HQL, JPQL)
Supports also NoSQL stores
Is pretty dead

Spring JDBC, Apache DbUtils, etc
Ease *some* of the JDBC pain
Copyright (c) 2009-2013 by Data Geekery GmbH.

Examples
Intro

SQL and Java

jOOQ

Examples

SQL is so much more

|
TEXT | VOTES |
RANK | PERCENT |
|-------------|-------|------------|---------|
|
Hibernate |
138 |
1 |
32 % |
|
jOOQ |
102 |
2 |
23 % |
| EclipseLink |
88 |
3 |
20 % |
|
JDBC |
53 |
4 |
12 % |
| Spring JDBC |
45 |
5 |
10 % |

Copyright (c) 2009-2013 by Data Geekery GmbH.
Intro

SQL and Java

jOOQ

SQL is so much more

SELECT

p.text,
p.votes,
DENSE_RANK() OVER (ORDER BY p.votes DESC) AS "rank",
LPAD(
(p.votes * 100 / SUM(p.votes) OVER ()) || ' %',
4, ' '
) AS "percent"
FROM
poll_options p
WHERE
p.poll_id = 12
ORDER BY p.votes DESC

Copyright (c) 2009-2013 by Data Geekery GmbH.

Examples
Intro

SQL and Java

jOOQ

The same with jOOQ

select (p.TEXT,
p.VOTES,
denseRank().over().orderBy(p.VOTES.desc()).as("rank"),
lpad(
p.VOTES.mul(100).div(sum(p.VOTES).over()).concat(" %"),
4, " "
).as("percent"))
.from
(POLL_OPTIONS.as("p"))
.where (p.POLL_ID.eq(12))
.orderBy(p.VOTES.desc());

Copyright (c) 2009-2013 by Data Geekery GmbH.

Examples
Intro

SQL and Java

jOOQ

The same with jOOQ in Scala (!)

select (p.TEXT,
p.VOTES,
denseRank() over() orderBy(p.VOTES desc) as "rank",
lpad(
(p.VOTES * 100) / (sum(p.VOTES) over()) || " %",
4, " "
) as "percent")
from
(POLL_OPTIONS as "p")
where
(p.POLL_ID === 12)
orderBy (p.VOTES desc)

Copyright (c) 2009-2013 by Data Geekery GmbH.

Examples
Intro

SQL and Java

jOOQ

Examples

Support
Access
CUBRID
DB2
Derby
Firebird
H2
HSQLDB
Ingres
Copyright (c) 2009-2013 by Data Geekery GmbH.

MariaDB
MySQL
Oracle
Postgres
SQL Server
SQLite
Sybase ASE
Sybase SQL Anywhere
Intro

Examples

Copyright (c) 2009-2013 by Data Geekery GmbH.

SQL and Java

jOOQ

Examples

jOOQ at Topconf 2013

  • 1.
    Get Back inControl of your SQL SQL and Java could work together so much better if we only let them. Copyright (c) 2009-2013 by Data Geekery GmbH.
  • 2.
    Intro SQL and Java jOOQ Examples Aboutme Java, SQL, PL/SQL 2001-2006 MSc Computer Science EPFL 2006-2009 Ergon Informatik AG, Zürich 2009-2013 Crealogix E-Banking AG, Zürich 2013 Adobe Systems Inc, Basel 2013 Data Geekery GmbH, Zürich Copyright (c) 2009-2013 by Data Geekery GmbH.
  • 3.
    Intro SQL and Java Aboutmy motivation SQL dominates database systems SQL seems «low level» and «dusty» SQL can do so much more SQL should be «sexy» again Copyright (c) 2009-2013 by Data Geekery GmbH. jOOQ Examples
  • 4.
    Intro About today History ofSQL in Java Persistence in Java today jOOQ jOOQ Examples Copyright (c) 2009-2013 by Data Geekery GmbH. SQL and Java jOOQ Examples
  • 5.
    Intro SQL and Java jOOQ SQLand Java - never ending story JDBC EJB 2.0 with EntityBeans Hibernate / TopLink EJB 3.0 with JPA 2.x iBATIS / JDO / SpringData / 1’000 others Copyright (c) 2009-2013 by Data Geekery GmbH. Examples
  • 6.
    Intro SQL and Java jOOQ JDBC PreparedStatementstmt = connection.prepareStatement( "SELECT text FROM products WHERE cust_id = ? AND value < ?"); stmt.setInt(1, custID); stmt.setBigDecimal(2, BigDecimal.ZERO); ResultSet rs = stmt.executeQuery(); while (rs.next()) { System.out.println(rs.getString("TEXT")); } Copyright (c) 2009-2013 by Data Geekery GmbH. Examples
  • 7.
    Intro SQL and Java JDBC– the naked truth 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: PreparedStatement stmt = connection.prepareStatement( "SELECT p.text txt" + (isAccount ? ", NVL(a.type, ?) " : "") + "FROM products p " + (isAccount ? " INNER JOIN accounts a USING (prod_id) " : "") + " WHERE p.cust_id = ? AND p.value < ?" + (isAccount ? " AND a.type LIKE '%" + type + "%'" : ""); stmt.setInt(1, defaultType); stmt.setInt(2, custID); stmt.setBigDecimal(3, BigDecimal.ZERO); ResultSet rs = stmt.executeQuery(); while (rs.next()) { Clob clob = rs.getClob("TEXT"); System.out.println(clob.getSubString(1, (int) clob.length()); } rs.close(); stmt.close(); Copyright (c) 2009-2013 by Data Geekery GmbH. jOOQ Examples
  • 8.
    Intro SQL and Java jOOQ Examples JDBC– the naked truth 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: PreparedStatement stmt = connection.prepareStatement( // "SELECT p.text txt" + // (isAccount ? ", NVL(a.type, ?) " : "") + // "FROM products p " + // Syntax error when isAccount == false (isAccount ? " INNER JOIN accounts a USING (prod_id) " : "") + // " WHERE p.cust_id = ? AND p.value < ?" + // (isAccount ? " AND a.type LIKE '%" + type + "%'" : ""); // Syntax error and SQL injection possible stmt.setInt(1, defaultType); // Wrong bind index stmt.setInt(2, custID); // stmt.setBigDecimal(3, BigDecimal.ZERO); // ResultSet rs = stmt.executeQuery(); // while (rs.next()) { Clob clob = rs.getClob("TEXT"); System.out.println(clob.getSubString(1, (int) clob.length()); } // // ojdbc6: clob.free() should be called // // rs.close(); stmt.close(); // close() not really in finally block // Copyright (c) 2009-2013 by Data Geekery GmbH.
  • 9.
    Intro SQL and Java jOOQ Examples JDBC– pros and cons JDBC Pros No restrictions (procedures, UDTs, vendor-specific features) Simple Fast JDBC Cons String-based No syntax checking Lots of code, flat / indexed variables Repetitive Vendor lock-in Copyright (c) 2009-2013 by Data Geekery GmbH.
  • 10.
    Intro SQL and Java EJB2.0 EntityBeans public interface CustomerRequest extends EJBObject { BigInteger getId(); String getText(); void setText(String text); @Override void remove(); } public interface CustomerRequestHome extends EJBHome { CustomerRequest create(BigInteger id); CustomerRequest find(BigInteger id); } Copyright (c) 2009-2013 by Data Geekery GmbH. jOOQ Examples
  • 11.
    Intro EJB 2.0 –the naked truth <weblogic-enterprise-bean> <ejb-name>com.example.CustomerRequestHome</ejb-name> <entity-descriptor> <pool> <max-beans-in-free-pool>100</max-beans-in-free-pool> </pool> <entity-cache> <max-beans-in-cache>500</max-beans-in-cache> <idle-timeout-seconds>10</idle-timeout-seconds> <concurrency-strategy>Database</concurrency-strategy> </entity-cache> <persistence> <delay-updates-until-end-of-tx>True</delay-updates-until-end-of-tx> </persistence> <entity-clustering> <home-is-clusterable>False</home-is-clusterable> <home-load-algorithm>round-robin</home-load-algorithm> </entity-clustering> </entity-descriptor> <transaction-descriptor/> <enable-call-by-reference>True</enable-call-by-reference> <jndi-name>com.example.CustomerRequestHome</jndi-name> </weblogic-enterprise-bean> Copyright (c) 2009-2013 by Data Geekery GmbH. SQL and Java jOOQ Examples
  • 12.
    Intro SQL and Java jOOQ EJB2.0 – pros and cons EJB 2.0 Pros Intuitive client code (create(), remove(), store()) Powerful (transactions, caching, etc.) EJB 2.0 Cons Not intuitive implementation (Home, conventions) Lots of configuration XDoclet Checked Exceptions (FinderException, CreateException) Repetitive (except with a code generator) Domain Model depends on container Copyright (c) 2009-2013 by Data Geekery GmbH. Examples
  • 13.
    Intro SQL and Java Hibernate– ORM Session session = sessionFactory.openSession(); session.beginTransaction(); session.save(new Event("Conference", new Date()); session.save(new Event("After Party", new Date()); List result = session.createQuery("from Event").list(); for (Event event : (List<Event>) result) { System.out.println("Event : " + event.getTitle()); } session.getTransaction().commit(); session.close(); Copyright (c) 2009-2013 by Data Geekery GmbH. jOOQ Examples
  • 14.
    Intro SQL and Java Hibernate– «navigation» List result = session.createQuery("from Event").list(); for (Event event : (List<Event>) result) { System.out.println("Participants of " + event); for (Person person : event.getParticipants()) { Company company = person.getCompany(); System.out.println(person + " (" + company + ")"); } } Copyright (c) 2009-2013 by Data Geekery GmbH. jOOQ Examples
  • 15.
    Intro SQL and Java jOOQ Hibernate– the naked truth <hibernate-mapping package="org.hibernate.tutorial.hbm"> <class name="Event" table="EVENTS"> <id name="id" column="EVENT_ID"> <generator class="increment"/> </id> <property name="date" type="timestamp" column="EVENT_DATE"/> <property name="title"/> <set name="participants" inverse="true"> <key column="eventId"/> <one-to-many entity-name="Person"/> </set> </class> </hibernate-mapping> Copyright (c) 2009-2013 by Data Geekery GmbH. Examples
  • 16.
    Intro Hibernate – prosand cons Hibernate Pros Very intuitive client code (POJOs) POJO code generator Objects can be «navigated» Hibernate implements JPA Hibernate Cons Hard to configure Caching is complex HQL is limited. SQL can do more. ORM impedance mismatch Copyright (c) 2009-2013 by Data Geekery GmbH. SQL and Java jOOQ Examples
  • 17.
    Intro SQL and Java jOOQ JPAand EJB 3.0 EntityManager em = factory.createEntityManager(); em.getTransaction().begin(); em.persist(new Event("Conference", new Date()); em.persist(new Event("After Party", new Date()); List result = em.createQuery("from Event").getResultList(); for (Event event : (List<Event>) result) { System.out.println("Event : " + event.getTitle()); } em.getTransaction().commit(); em.close(); Copyright (c) 2009-2013 by Data Geekery GmbH. Examples
  • 18.
    Intro SQL and Java jOOQ EJB3.0 – the naked truth @Entity @Table(name = "EVENTS") public class Event { private Long id; private String title; private Date date; @Id @GeneratedValue(generator = "increment") @GenericGenerator(name = "increment", strategy = "increment") public Long getId() { /* … */ } @Temporal(TemporalType.TIMESTAMP) @Column(name = "EVENT_DATE") public Date getDate() { /* … */ } Copyright (c) 2009-2013 by Data Geekery GmbH. Examples
  • 19.
    Intro SQL and Java jOOQ Examples Criteria– the naked truth EntityManager em= ... CriteriaBuilder builder = em.getCriteriaBuilder(); CriteriaQuery<Person> criteria = builder.createQuery(Person.class); Root<Person> person = criteria.from(Person.class); Predicate condition = builder.gt(person.get(Person_.age), 20); criteria.where(condition); TypedQuery<Person> query = em.createQuery(query); List<Person> result = query.getResultList(); Copyright (c) 2009-2013 by Data Geekery GmbH.
  • 20.
    Intro SQL and Java jOOQ JPA– pros and cons JPA Facts Hibernate HQL => JPQL Hibernate XML mapping => annotations Hibernate Sessions => EntityManager JPA Pros Next standard after EJB 2.0 Good implementations, such as Hibernate, EclipseLink JPA Cons CriteriaQuery Copyright (c) 2009-2013 by Data Geekery GmbH. Examples
  • 21.
    Intro SQL and Java jOOQ Whatelse is there? iBATIS / MyBatis XML based. SQL is externalised Active, but seems to be at the end of its hype cycle JDO Has JDOQL (similar to HQL, JPQL) Supports also NoSQL stores Is pretty dead Spring JDBC, Apache DbUtils, etc Ease *some* of the JDBC pain Copyright (c) 2009-2013 by Data Geekery GmbH. Examples
  • 22.
    Intro SQL and Java jOOQ Examples SQLis so much more | TEXT | VOTES | RANK | PERCENT | |-------------|-------|------------|---------| | Hibernate | 138 | 1 | 32 % | | jOOQ | 102 | 2 | 23 % | | EclipseLink | 88 | 3 | 20 % | | JDBC | 53 | 4 | 12 % | | Spring JDBC | 45 | 5 | 10 % | Copyright (c) 2009-2013 by Data Geekery GmbH.
  • 23.
    Intro SQL and Java jOOQ SQLis so much more SELECT p.text, p.votes, DENSE_RANK() OVER (ORDER BY p.votes DESC) AS "rank", LPAD( (p.votes * 100 / SUM(p.votes) OVER ()) || ' %', 4, ' ' ) AS "percent" FROM poll_options p WHERE p.poll_id = 12 ORDER BY p.votes DESC Copyright (c) 2009-2013 by Data Geekery GmbH. Examples
  • 24.
    Intro SQL and Java jOOQ Thesame with jOOQ select (p.TEXT, p.VOTES, denseRank().over().orderBy(p.VOTES.desc()).as("rank"), lpad( p.VOTES.mul(100).div(sum(p.VOTES).over()).concat(" %"), 4, " " ).as("percent")) .from (POLL_OPTIONS.as("p")) .where (p.POLL_ID.eq(12)) .orderBy(p.VOTES.desc()); Copyright (c) 2009-2013 by Data Geekery GmbH. Examples
  • 25.
    Intro SQL and Java jOOQ Thesame with jOOQ in Scala (!) select (p.TEXT, p.VOTES, denseRank() over() orderBy(p.VOTES desc) as "rank", lpad( (p.VOTES * 100) / (sum(p.VOTES) over()) || " %", 4, " " ) as "percent") from (POLL_OPTIONS as "p") where (p.POLL_ID === 12) orderBy (p.VOTES desc) Copyright (c) 2009-2013 by Data Geekery GmbH. Examples
  • 26.
    Intro SQL and Java jOOQ Examples Support Access CUBRID DB2 Derby Firebird H2 HSQLDB Ingres Copyright(c) 2009-2013 by Data Geekery GmbH. MariaDB MySQL Oracle Postgres SQL Server SQLite Sybase ASE Sybase SQL Anywhere
  • 27.
    Intro Examples Copyright (c) 2009-2013by Data Geekery GmbH. SQL and Java jOOQ Examples