<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8884584404576003487</id><updated>2026-09-29T01:57:32.017-04:00</updated><category term="oradb"/><category term="howto"/><category term="oracle"/><category term="obiee"/><category term="database"/><category term="work"/><category term="funny"/><category term="development"/><category term="oow"/><category term="dba"/><category term="2010"/><category term="sql"/><category term="design"/><category term="rant"/><category term="apex"/><category term="collaborate"/><category term="2009"/><category term="plsql"/><category term="humility"/><category term="11g"/><category term="random"/><category term="install"/><category term="datawarehouse"/><category term="blogging"/><category term="soug"/><category term="kate"/><category term="family"/><category term="2011"/><category term="jobs"/><category term="odtug"/><category term="tshirts"/><category term="exadata"/><category term="testing"/><category term="wtf"/><category term="certification"/><category term="code"/><category term="discipline"/><category term="kscope"/><category term="security"/><category term="tools"/><category term="2012"/><category term="performance"/><category term="ubuntu"/><category term="1Z0-052"/><category term="constraints"/><category term="ebs"/><category term="java"/><category term="presentation"/><category term="sql developer"/><category term="documentation"/><category term="failed"/><category term="oel"/><category term="virtualbox"/><category term="instrumentation"/><category term="style"/><category term="jpiwowar"/><category term="2013"/><category term="debug"/><category term="error"/><category term="gotcha"/><category term="utilities"/><category term="baseball"/><category term="data"/><category term="life"/><category term="mysql"/><category term="puzzle"/><category term="LC"/><category term="ddl"/><category term="mcohen"/><category term="pmdv"/><category term="reports"/><category term="rpd"/><category term="tsimpson"/><category term="twitter"/><category term="cdc"/><category term="cio"/><category term="eaviles"/><category term="google"/><category term="ideas"/><category term="null"/><category term="obia"/><category term="open source"/><category term="parallel"/><category term="rman"/><category term="views"/><category term="ace"/><category term="android"/><category term="architecture"/><category term="big_data"/><category term="domain"/><category term="gmyers"/><category term="hertz"/><category term="modeling"/><category term="moneill"/><category term="oltp"/><category term="process"/><category term="profiling"/><category term="social media"/><category term="sqlunit"/><category term="triggers"/><category term="tuning"/><category term="udt"/><category term="utl_file"/><category term="%ROWTYPE"/><category term="10g"/><category term="2008"/><category term="ORA-08177"/><category term="ai"/><category term="answers"/><category term="avis"/><category term="cloud"/><category term="coherence"/><category term="dbms_application_info"/><category term="dbms_cdc_publish"/><category term="dbms_crypto"/><category term="dbms_job"/><category term="dbms_session"/><category term="dbms_sql"/><category term="devops"/><category term="etl"/><category term="flashback"/><category term="kpedersen"/><category term="nosql"/><category term="partition"/><category term="pdi"/><category term="support"/><category term="utl_tcp"/><category term="vfagundo"/><category term="web2.0"/><category term="windows"/><category term="xe"/><category term="2015"/><category term="2016"/><category term="OAUG"/><category term="ORA-00119"/><category term="ORA-00130"/><category term="ORA-01578"/><category term="ORA-01820"/><category term="ORA-08103"/><category term="ORA-1034"/><category term="ORA-12154"/><category term="ORA-12533"/><category term="ORA-12571"/><category term="ORA-12705"/><category term="ORA-22816"/><category term="ORA-27504"/><category term="ORA-28547"/><category term="TNS-03505"/><category term="apex_util"/><category term="autism"/><category term="backup"/><category term="beer"/><category term="bip"/><category term="book"/><category term="cyanogenmod"/><category term="data integration"/><category term="data mining"/><category term="datapump"/><category term="dbms_metadata"/><category term="dbms_output"/><category term="dbms_profiler"/><category term="dbms_repair"/><category term="dbms_utility"/><category term="dbs"/><category term="decode"/><category term="developer"/><category term="discoverer"/><category term="exad"/><category term="exalogic"/><category term="excel"/><category term="fmw"/><category term="hkhalaf"/><category term="ioug"/><category term="network"/><category term="oda"/><category term="openoffice"/><category term="optimizer"/><category term="pentaho"/><category term="regexp_replace"/><category term="revolutionmoney"/><category term="sequences"/><category term="source control"/><category term="sqlplus"/><category term="tables"/><category term="totfj"/><category term="travel"/><category term="triathlon"/><category term="troubleshooting"/><category term="usaa"/><category term="virtual column"/><category term="weblogic"/><category term="wellcare"/><title type='text'>ORACLENERD</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default?alt=atom'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default?alt=atom&amp;start-index=26&amp;max-results=25'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>801</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-516327848970487839</id><published>2026-09-28T21:46:01.278-04:00</published><updated>2026-09-28T21:46:01.278-04:00</updated><title type='text'>The System Still Works: The Algorithmic Arms Race</title><content type='html'>&lt;!-- Title: The System Still Works: The Algorithmic Arms Race --&gt;
&lt;p&gt;Back in May, in &lt;a href=&quot;https://www.oraclenerd.com/2026/05/the-system-works.html&quot;&gt;The System Works&lt;/a&gt;, I wrote about the Sunday session where I finally set &lt;a href=&quot;https://antigravity.google/&quot;&gt;Antigravity&lt;/a&gt; loose to map out twenty years of gut feelings about the American healthcare system.&lt;/p&gt;

&lt;p&gt;I wrote about the plastic card illusion: walking into a clinic with no insurance and paying a $115 copay, versus handing over an insurance card and watching the bill explode to $400. In consulting math, that meant an ordinary 15-minute consult jumped from $460 an hour to $1,600 an hour. Nothing about the clinical diagnosis had changed. Only the billing plumbing had.&lt;/p&gt;

&lt;p&gt;The core thesis we landed on that Sunday wasn&#39;t that the system was broken. It was the opposite: &lt;strong&gt;the system is working perfectly.&lt;/strong&gt; It is an autopoietic machine, an economic ecosystem designed to reproduce its own administrative complexity and extract maximum yield.&lt;/p&gt;

&lt;p&gt;I ended that post noting that while the system hadn&#39;t changed, I could finally see the paths, the rules, and why people kept ending up in the exact same traps.&lt;/p&gt;

&lt;p&gt;Well, last week, Blue Cross Blue Shield published an analysis that proved the machine has found its next gear.&lt;/p&gt;

&lt;h2&gt;The $1 Billion Query: Mining for Acuity&lt;/h2&gt;

&lt;p&gt;According to a &lt;a href=&quot;https://www.bcbs.com/about-us/association-news/bcbsa-analysis-ai-coding-tools-affects-healthcare-costs&quot;&gt;new analysis of claims data by the Blue Cross Blue Shield Association&lt;/a&gt;, the rapid adoption of AI coding tools by hospitals added an estimated &lt;strong&gt;$942 million&lt;/strong&gt; in commercial healthcare spending between 2023 and 2025 alone.&lt;/p&gt;

&lt;p&gt;More than 60% of hospital systems are now running AI-enabled revenue cycle software. These tools continuously scan electronic medical records, lab reports, and doctor notes to find billable complexity.&lt;/p&gt;

&lt;p&gt;And what did all those millions in new revenue buy in terms of actual medicine?&lt;/p&gt;

&lt;p&gt;Zero.&lt;/p&gt;

&lt;p&gt;BCBSA looked closely at patients undergoing major bowel surgery. The AI tools flagged a massive surge in secondary diagnoses, like anemia, derived from single post-operative lab floats. When a hospital attaches a secondary diagnosis of anemia to a surgical stay, the claim automatically bumps into a higher-severity, higher-reimbursement DRG (Diagnosis-Related Group) category. Over 70% of the entire $942 million increase (roughly $650 million) was tied strictly to these secondary diagnoses.&lt;/p&gt;

&lt;p&gt;Yet when researchers looked at the clinical charts, there was no corresponding increase in treatments. No uptick in blood transfusions. No change in medication. No change in bedside recovery time.&lt;/p&gt;

&lt;p&gt;Luke Chalker, BCBSA&#39;s senior vice president of product and data science, summarized the finding with brutal clarity:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;&amp;quot;The disconnect between diagnoses and treatment suggests that AI is identifying more billable conditions, not sicker patients.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you&#39;re a data person, read that sentence again. That is not a bug. That is an optimization routine running exactly to spec.&lt;/p&gt;

&lt;h2&gt;The 74,000-Code Moat&lt;/h2&gt;

&lt;p&gt;For decades, healthcare policymakers and insurers built a labyrinth of classification. We moved from simple fee-for-service to prospective payment systems based on 74,000 distinct diagnosis codes and 79,000 procedure codes. The stated goal was accuracy and granular clinical documentation.&lt;/p&gt;

&lt;p&gt;The unstated reality was that human beings cannot hold 74,000 codes in their heads. Independent medical practices couldn&#39;t afford armies of certified coders, which accelerated the collapse of private practice and forced doctors into the arms of massive hospital conglomerates.&lt;/p&gt;

&lt;p&gt;And now, the conglomerates have done what every well-capitalized enterprise does when faced with a complex rules engine: they automated it.&lt;/p&gt;

&lt;p&gt;They pointed large language models and machine-learning classifiers directly at the EHR data lake. The algorithm doesn&#39;t ask if a patient feels better, or if a post-op hemoglobin dip is clinically meaningful. The algorithm asks a purely relational question: &lt;em&gt;Does this float value in table A legally support a secondary modifier in table B that increases the payout in table C?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The code is no longer a proxy for care. The code is the product.&lt;/p&gt;

&lt;h2&gt;The Press Release: Setting the Narrative&lt;/h2&gt;

&lt;p&gt;What makes this entire situation so fascinating from a systems perspective is the delivery mechanism. This wasn&#39;t a leaked internal memo. This was a &lt;strong&gt;press release&lt;/strong&gt; blasted out by the Blue Cross Blue Shield Association to major outlets like Reuters.&lt;/p&gt;

&lt;p&gt;Why is a massive insurance conglomerate publicly complaining that hospitals are out-coding them?&lt;/p&gt;

&lt;p&gt;Because they are setting the narrative.&lt;/p&gt;

&lt;p&gt;As we traced in the blueprints of &lt;em&gt;The Perfect Machine&lt;/em&gt;, Blue Cross was originally born in 1929 at Baylor University. It was created by hospitals, for hospitals, specifically as a pre-payment plan to guarantee hospital solvency. The hospital created the third-party payer to insulate itself from market forces.&lt;/p&gt;

&lt;p&gt;For nearly a century, the two sides grew together. Now, the hospitals have turned loose algorithms that out-optimize the insurer&#39;s own rulebook. By blasting out a press release, BCBSA is establishing a public scapegoat for why your employer&#39;s health premiums are going to spike another 7% next year. They are pointing the finger squarely at the hospital bots.&lt;/p&gt;

&lt;p&gt;But make no mistake: this is a two-sided bot war. Insurers aren&#39;t innocent victims. For the last five years, major health plans have deployed their own automated actuarial algorithms (like Cigna&#39;s PXDX and UnitedHealth&#39;s nH Predict) to batch-deny claims in 1.2 seconds without human review. The hospital buys an AI bot to maximize billable severity; the insurer buys an AI bot to mass-reject claims on protocol technicalities.&lt;/p&gt;

&lt;p&gt;Two multi-billion-dollar machine-learning networks are now trading transactions back and forth across an opaque API perimeter. Neither machine cares about the human lying in the hospital bed. The patient is just the transaction payload passing between them.&lt;/p&gt;

&lt;h2&gt;The System Still Works&lt;/h2&gt;

&lt;p&gt;When you see headlines about AI adding $1 billion to hospital bills, the natural reaction is to throw up your hands and say, &amp;quot;Healthcare is completely broken.&amp;quot;&lt;/p&gt;

&lt;p&gt;It&#39;s not.&lt;/p&gt;

&lt;p&gt;If you build a system where the customer does not pay, where the price signal is illegal or hidden, where payments are determined by an arbitrary 74,000-node taxonomy, and where survival depends on administrative volume, you will get autonomous code-mining bots every single time.&lt;/p&gt;

&lt;p&gt;In May, I wrote that once you see the plumbing, you stop looking for villains and start understanding the incentives. The BCBSA report isn&#39;t evidence of a broken system. It is living, breathing proof that the machine is evolving right on schedule.&lt;/p&gt;

&lt;p&gt;&lt;hr/&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Architected by Chet, written by Gemini 3.1 Pro&lt;/em&gt;&lt;/p&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/516327848970487839/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/516327848970487839' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/516327848970487839'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/516327848970487839'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2026/09/the-system-still-works-algorithmic-arms.html' title='The System Still Works: The Algorithmic Arms Race'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-4305127473253513700</id><published>2026-09-27T12:48:14.894-04:00</published><updated>2026-09-27T12:48:14.895-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="architecture"/><category scheme="http://www.blogger.com/atom/ns#" term="modeling"/><title type='text'>When the Guardrail Stops Guarding</title><content type='html'>  &lt;p&gt;A few months ago, in &lt;a href=&quot;https://www.oraclenerd.com/2026/05/you-can-point-foreign-key-where.html&quot;&gt;You Can Point a Foreign Key Where?!&lt;/a&gt;, we looked at
  pointing foreign keys to unique candidate keys instead of traditional surrogate IDs.&lt;/p&gt;
    
    &lt;p&gt;In the comments, Tom offered an essential reminder from decades in the trenches:&lt;/p&gt;
    
    &lt;blockquote&gt;
      &lt;p&gt;&lt;em&gt;&amp;quot;You and I have decades now of CREATE TABLE... and those decades have shown us the only thing that is truly immutable are the things stakeholders
  tell us are absolutely not immutable... business codes have a way of becoming less immutable across years. They get renamed, merged, generally f-d up all the time
  and when a new C-whatever comes in who likes SOON instead of ASAP, you&amp;#39;re cooked.&amp;quot;&lt;/em&gt;&lt;/p&gt;
    &lt;/blockquote&gt;
    
    &lt;p&gt;Tom was arguing for surrogate keys to separate meaning from relational identity. He was right. Business vocabulary is fluid. What feels permanent during sprint
  planning rarely stays permanent across three fiscal years.&lt;/p&gt;
    
    &lt;p&gt;That brings us to a design choice many of us reach for when standing up a new feature: skipping the reference table entirely and putting business enums directly
  into a table &lt;code&gt;CHECK&lt;/code&gt; constraint.&lt;/p&gt;
    
    &lt;pre&gt;&lt;code&gt;CREATE TABLE orders (
        order_id     NUMBER GENERATED BY DEFAULT AS IDENTITY,
        order_date   DATE NOT NULL,
        order_status VARCHAR2(20) NOT NULL,
        CONSTRAINT pk_orders PRIMARY KEY (order_id),
        CONSTRAINT ck_orders_status 
            CHECK (order_status IN (&#39;OPEN&#39;, &#39;PENDING&#39;, &#39;SHIPPED&#39;, &#39;CANCELLED&#39;))
    );&lt;/code&gt;&lt;/pre&gt;
    
    &lt;p&gt;To be clear: this is not a post against &lt;code&gt;CHECK&lt;/code&gt; constraints. &lt;code&gt;CHECK&lt;/code&gt; constraints are indispensable. This is a post about which rules they
  can actually hold.&lt;/p&gt;
    
    &lt;p&gt;Putting an enum into a &lt;code&gt;CHECK&lt;/code&gt; constraint looks tidy, declarative, and completely self-contained. It avoids spinning up another table, mapping
  another entity, or coordinating extra seed files. In the moment, it feels like disciplined engineering.&lt;/p&gt;
    
    &lt;p&gt;Until the business evolves, and the guardrail quietly stops guarding.&lt;/p&gt;
    
    &lt;h2&gt;The Silent Failure: Enforcing Neither&lt;/h2&gt;
    
    &lt;p&gt;The standard objection to putting enums in &lt;code&gt;CHECK&lt;/code&gt; constraints is migration friction. We have all heard the complaint: adding a status requires an
  &lt;code&gt;ALTER TABLE&lt;/code&gt;, table locks, and coordinated deployments instead of a simple &lt;code&gt;INSERT&lt;/code&gt;.&lt;/p&gt;
    
    &lt;p&gt;That argument is true, but it is an ergonomic argument. A determined engineering team can easily wave it off as an acceptable deployment cost.&lt;/p&gt;
    
    &lt;p&gt;The fatal problem with an enum &lt;code&gt;CHECK&lt;/code&gt; constraint is not operational friction. It is structural failure.&lt;/p&gt;
    
    &lt;p&gt;Consider Tom&amp;#39;s scenario: leadership decides that &lt;code&gt;&amp;#39;PENDING&amp;#39;&lt;/code&gt; is too vague. From now on, operations needs to split future orders into
  &lt;code&gt;&amp;#39;AWAITING_PAYMENT&amp;#39;&lt;/code&gt; and &lt;code&gt;&amp;#39;AWAITING_STOCK&amp;#39;&lt;/code&gt;.&lt;/p&gt;
    
    &lt;p&gt;What happens to existing records? The business does not want to rewrite history. The thousands of closed orders that passed through &lt;code&gt;&amp;#39;PENDING&amp;#39;
  &lt;/code&gt; over the last two years need to remain untouched.&lt;/p&gt;
    
    &lt;p&gt;Now look at what happens to your constraint:&lt;/p&gt;
    
    &lt;pre&gt;&lt;code&gt;ALTER TABLE orders DROP CONSTRAINT ck_orders_status;
    
    ALTER TABLE orders ADD CONSTRAINT ck_orders_status
        CHECK (order_status IN (
            &#39;OPEN&#39;, 
            &#39;PENDING&#39;, 
            &#39;AWAITING_PAYMENT&#39;, 
            &#39;AWAITING_STOCK&#39;, 
            &#39;SHIPPED&#39;, 
            &#39;CANCELLED&#39;
        ));&lt;/code&gt;&lt;/pre&gt;
    
    &lt;p&gt;Because a table constraint evaluates every row equally across the entire table, &lt;code&gt;&amp;#39;PENDING&amp;#39;&lt;/code&gt; must remain in the allowed list forever just to
  keep historical rows valid.&lt;/p&gt;
    
    &lt;p&gt;The moment history and future diverge, the &lt;code&gt;CHECK&lt;/code&gt; constraint is forced to permit both. And the moment it permits both, it can no longer prevent an
  application bug from inserting a brand new &lt;code&gt;&amp;#39;PENDING&amp;#39;&lt;/code&gt; order tomorrow morning.&lt;/p&gt;
    
    &lt;p&gt;You thought you had an automated guardrail protecting business integrity. What you actually have is a decorative plaque. The constraint that was written to
  enforce valid state transitions has quietly stopped constraining.&lt;/p&gt;

    &lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left; padding: 1em 0;&quot;&gt;
      &lt;img alt=&quot;A lonely gate on a sidewalk with open grass on either side, labeled CHECK (order_status IN (&#39;OPEN&#39;, &#39;PENDING&#39;, ...))&quot; border=&quot;0&quot; 
  src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAFacOjbDOl7sOcLSey25StrBZl-bt06hnfFxM9dltD2I8b0pem-kFFlagus9Ty8383fPvDE9zBVgKnp-dT64n8figud7jncuvekssOR8CAm5CmUFKZ58V30xzUA-f-HVBpDummRK02Yr7zqd8jzX8ONwbSIkaoScKoQK-Jnd55ifV4LIaGkIgbVbsaGA/s320/check_constraints.jpg&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;
    &lt;/div&gt;

    &lt;h2&gt;Temporal Boundaries Trump Hardcoded Strings&lt;/h2&gt;
    
    &lt;p&gt;When we move business vocabulary out of DDL and into a proper reference table, we don&amp;#39;t resort to a lazy &lt;code&gt;is_active&lt;/code&gt; boolean flag either. As we
  saw in &lt;a href=&quot;https://www.oraclenerd.com/2026/09/the-boolean-is-lying-to-you.html&quot;&gt;The Boolean is Lying to You&lt;/a&gt;, booleans erase history.&lt;/p&gt;
    
    &lt;p&gt;Instead, we use explicit temporal boundaries:&lt;/p&gt;
    
    &lt;pre&gt;&lt;code&gt;CREATE TABLE order_statuses (
        status_id            NUMBER GENERATED BY DEFAULT AS IDENTITY,
        status_code          VARCHAR2(20) NOT NULL,
        description          VARCHAR2(100) NOT NULL,
        display_seq          NUMBER NOT NULL,
        effective_start_date TIMESTAMP WITH TIME ZONE NOT NULL,
        effective_end_date   TIMESTAMP WITH TIME ZONE,
        --
        CONSTRAINT pk_order_statuses PRIMARY KEY (status_id),
        CONSTRAINT uq_order_statuses_code UNIQUE (status_code),
        CONSTRAINT ck_order_statuses_dates 
            CHECK (effective_end_date IS NULL OR effective_end_date &amp;gt;= effective_start_date)
    );&lt;/code&gt;&lt;/pre&gt;
    
    &lt;p&gt;&lt;em&gt;(Notice where the &lt;code&gt;CHECK&lt;/code&gt; constraint lives: validating that an end date cannot precede a start date. A mathematical and calendar rule, exactly
  where it belongs.)&lt;/em&gt;&lt;/p&gt;
    
    &lt;p&gt;When the business retires &lt;code&gt;&amp;#39;PENDING&amp;#39;&lt;/code&gt;, we don&amp;#39;t touch the &lt;code&gt;orders&lt;/code&gt; table. We update the lookup table:&lt;/p&gt;
    
    &lt;pre&gt;&lt;code&gt;UPDATE order_statuses 
       SET effective_end_date = SYSTIMESTAMP 
     WHERE status_code = &#39;PENDING&#39;;
    
    INSERT INTO order_statuses (status_code, description, display_seq, effective_start_date)
    VALUES (&#39;AWAITING_PAYMENT&#39;, &#39;Awaiting Payment&#39;, 20, SYSTIMESTAMP);
    
    INSERT INTO order_statuses (status_code, description, display_seq, effective_start_date)
    VALUES (&#39;AWAITING_STOCK&#39;, &#39;Awaiting Stock&#39;, 30, SYSTIMESTAMP);&lt;/code&gt;&lt;/pre&gt;
    
    &lt;p&gt;Every historical order referencing &lt;code&gt;&amp;#39;PENDING&amp;#39;&lt;/code&gt; remains fully valid. Meanwhile, any active query or UI dropdown filters on
  &lt;code&gt;effective_end_date IS NULL&lt;/code&gt; (or evaluates whether &lt;code&gt;SYSTIMESTAMP&lt;/code&gt; falls between the start and end dates). New orders cannot select &lt;code&gt;&amp;#39;
  PENDING&amp;#39;&lt;/code&gt;. Old orders cannot be corrupted.&lt;/p&gt;
    
    &lt;p&gt;Better yet, temporal versioning gives you future-dating for free. When operations announces that a new status takes effect on January 1, you insert the row
  today with an &lt;code&gt;effective_start_date&lt;/code&gt; of January 1. At midnight, it activates automatically. No midnight deployments, no emergency patches, and zero table
  locks.&lt;/p&gt;
    
    &lt;h2&gt;The Metadata Leak&lt;/h2&gt;
    
    &lt;p&gt;A &lt;code&gt;CHECK&lt;/code&gt; constraint treats an enum as a naked, isolated literal. But business vocabulary never stays naked.&lt;/p&gt;
    
    &lt;p&gt;Before long, the rest of the team needs context:&lt;/p&gt;
    &lt;ul&gt;
      &lt;li&gt;The user interface needs human-readable labels and a coherent sort order rather than raw database codes.&lt;/li&gt;
      &lt;li&gt;Reporting pipelines need to know which statuses represent terminal states versus active work in progress.&lt;/li&gt;
      &lt;li&gt;Audit systems need to know what the valid vocabulary looked like on a specific date two years ago.&lt;/li&gt;
    &lt;/ul&gt;
    
    &lt;p&gt;In a reference table, those attributes have a natural home (&lt;code&gt;display_seq&lt;/code&gt;, &lt;code&gt;effective_start_date&lt;/code&gt;, &lt;code&gt;description&lt;/code&gt;). The database
  acts as a shared, queryable source of truth.&lt;/p&gt;

    &lt;p&gt;In a &lt;code&gt;CHECK&lt;/code&gt; constraint, the database cannot hold that context. So the context leaks. It leaks into frontend TypeScript switch statements, backend
  YAML files, and hardcoded reporting filters. You didn&amp;#39;t avoid complexity; you just forced your schema to live in five different application files instead of the
  database.&lt;/p&gt;

    &lt;h2&gt;The Portable Rule&lt;/h2&gt;

    &lt;p&gt;This brings us to a reliable boundary for schema design:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;Use CHECK constraints for mathematical, temporal, and physical invariants.&lt;/strong&gt; &lt;code&gt;quantity &amp;gt; 0&lt;/code&gt;. &lt;code&gt;percentage BETWEEN 0 AND
  100&lt;/code&gt;. &lt;code&gt;end_date &amp;gt;= start_date&lt;/code&gt;. Cross-column requirements like requiring a card token when payment type is credit card. These are arithmetic and
  physical boundaries. They do not drift because of a company rebrand.&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Use Lookup Tables for business vocabulary and lifecycle states.&lt;/strong&gt; Order statuses, workflow stages, customer tiers, reason codes. Anything that
  product owners or executives might refine next quarter.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;If changing the rule violates the laws of mathematics or calendar time, it belongs in DDL. If changing the rule requires a conversation with product management,
  it belongs in a table.&lt;/p&gt;

    &lt;h2&gt;Scoped Optimization and AI&lt;/h2&gt;

    &lt;p&gt;In my reply to Tom on that earlier post, I noted that keeping enums out of &lt;code&gt;CHECK&lt;/code&gt; constraints is one of the fundamentals that requires an explicit
  waiver in my coding assistant instruction files.&lt;/p&gt;

    &lt;p&gt;It is worth asking why AI assistants reach for &lt;code&gt;CHECK (status IN (...))&lt;/code&gt; almost every single time they are asked to scaffold a schema.&lt;/p&gt;

    &lt;p&gt;The assistant is not being lazy. It is behaving exactly like an application developer focused on a single user story: it is correctly optimizing for a scope
  that does not include the third fiscal year.&lt;/p&gt;

    &lt;p&gt;Within the boundaries of a single prompt, a self-contained &lt;code&gt;CHECK&lt;/code&gt; constraint satisfies every immediate functional requirement. It compiles cleanly
  in thirty lines of generated SQL, avoids creating auxiliary tables, and avoids the cognitive overhead of foreign keys. The model&amp;#39;s horizon is the current
  response window. It has no reason to care what happens when marketing changes &lt;code&gt;&amp;#39;ASAP&amp;#39;&lt;/code&gt; to &lt;code&gt;&amp;#39;SOON&amp;#39;&lt;/code&gt; thirty-six months from now.
  &lt;/p&gt;

    &lt;p&gt;If we don&amp;#39;t guide our tools with clear fundamentals, they will produce code that is locally optimal and globally fragile.&lt;/p&gt;

    &lt;p&gt;Take the time to build the reference table, give it proper temporal boundaries, and establish the foreign key. It is the only way to ensure that when your data
  models meet the third fiscal year, the database is still the place telling the truth.&lt;/p&gt;

    &lt;p&gt;&lt;hr/&gt;&lt;/p&gt;

    &lt;p&gt;&lt;em&gt;The arguments are mine. Drafted with Gemini 3.8 Flash.&lt;/em&gt;&lt;/p&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/4305127473253513700/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/4305127473253513700' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/4305127473253513700'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/4305127473253513700'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2026/09/when-guardrail-stops-guarding.html' title='When the Guardrail Stops Guarding'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAFacOjbDOl7sOcLSey25StrBZl-bt06hnfFxM9dltD2I8b0pem-kFFlagus9Ty8383fPvDE9zBVgKnp-dT64n8figud7jncuvekssOR8CAm5CmUFKZ58V30xzUA-f-HVBpDummRK02Yr7zqd8jzX8ONwbSIkaoScKoQK-Jnd55ifV4LIaGkIgbVbsaGA/s72-c/check_constraints.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-2332575659390405204</id><published>2026-09-16T21:05:04.834-04:00</published><updated>2026-09-27T11:43:34.930-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="architecture"/><category scheme="http://www.blogger.com/atom/ns#" term="modeling"/><title type='text'> Every JSON Column Has a Schema</title><content type='html'>&lt;p&gt;&lt;em&gt;The arguments are mine. The typing was not.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let&#39;s complete the trilogy (That&#39;s probably a lie...).&lt;/p&gt;

&lt;p&gt;Over the last two weeks, we&#39;ve picked apart the boolean:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;In the warehouse (OLAP), a boolean &lt;strong&gt;duplicates&lt;/strong&gt; a truth that already exists elsewhere (your temporal boundaries).&lt;/li&gt;
  &lt;li&gt;In an operational system (OLTP), a boolean &lt;strong&gt;destroys&lt;/strong&gt; a truth that did exist (wiping out history and sequence).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A JSON column does something far sneakier: &lt;strong&gt;it never declares a truth, so nothing can ever contradict it.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;The Unfalsifiable Blob&lt;/h2&gt;

&lt;p&gt;A shapeless blob cannot be wrong, because there is no declared shape for it to violate.&lt;/p&gt;

&lt;p&gt;Think about what happens when you create a proper relational column. You declare &lt;code&gt;customer_id INTEGER NOT NULL REFERENCES customers(id)&lt;/code&gt;. You have drawn a hard line in the sand. If the application tries to insert &lt;code&gt;&#39;banana&#39;&lt;/code&gt;, the database rejects it. If it tries to insert an orphaned customer, the database rejects it. The engine knows what is true and what is a lie, and it protects you.&lt;/p&gt;

&lt;p&gt;Now look at a JSON column.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code&gt;{&quot;customer_id&quot;: 123}&lt;/code&gt; is valid JSON.&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;{&quot;customer_id&quot;: &quot;123&quot;}&lt;/code&gt; is valid JSON.&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;{&quot;customerId&quot;: null}&lt;/code&gt; is valid JSON.&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;{&quot;cust_id&quot;: &quot;banana&quot;}&lt;/code&gt; is valid JSON.&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;{}&lt;/code&gt; is valid JSON.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The database accepts every single one of those rows without blinking. It writes them to disk, returns a &lt;code&gt;200 OK&lt;/code&gt;, and goes about its day. Why? Because you never declared a contract. You never told the database what &quot;right&quot; looks like, so nothing can ever be &quot;wrong.&quot;&lt;/p&gt;

&lt;p&gt;Until six months later, when the reporting query blows up. At that point, you don&#39;t have a data model: you have vibes and a support ticket.&lt;/p&gt;

&lt;h2&gt;Watching From the Outside&lt;/h2&gt;

&lt;p&gt;I know why people do it. A new feature lands on your desk, the product manager is still fuzzy on the specs, the attributes will probably change next sprint, and you just need to get the code out the door. So you slap a &lt;code&gt;payload&lt;/code&gt; JSON column on the table and tell yourself you&#39;re being agile.&lt;/p&gt;

&lt;p&gt;I&#39;ve never done this. Not with JSON.&lt;/p&gt;

&lt;p&gt;Booleans, sure. I will readily admit to that sin. I&#39;ve slapped an &lt;code&gt;is_active&lt;/code&gt; flag on a table and paid for it later. But dumping application objects into a JSON column is one I have only ever watched from the outside, which is its own kind of education.&lt;/p&gt;

&lt;p&gt;If you come from the database world, the foundational rule has always been simple: put integrity constraints as close to the data as humanly possible. The database exists to protect the data from the application, because applications get rewritten every two years, but data lives forever.&lt;/p&gt;

&lt;p&gt;When you drop an unconstrained JSON blob into a table, you&#39;re betting that every future engineer touching that application will remember to enforce every single implicit business rule in code.&lt;/p&gt;

&lt;p&gt;Spoiler: they won&#39;t.&lt;/p&gt;

&lt;h2&gt;Rebuilding the Schema, Badly&lt;/h2&gt;

&lt;p&gt;Someone reading this will inevitably push back: &quot;Wait, you can enforce integrity on a JSON column!&quot;&lt;/p&gt;

&lt;p&gt;And you can. Modern engines will let you bolt integrity back onto a document. Postgres will happily take a &lt;code&gt;CHECK&lt;/code&gt; constraint on an extracted jsonb path. You can create generated columns with foreign keys, and you can build functional GIN or B-tree indexes against nested attributes.&lt;/p&gt;

&lt;p&gt;Technically, you can do it. But look at what you are actually doing: you are reconstructing, one painful piece at a time, the relational schema you declined to write in the first place, using an esoteric, vendor-specific syntax that nobody on your team will recognize in a year.&lt;/p&gt;

&lt;p&gt;You didn&#39;t avoid the schema. You just decided to rebuild a worse version of it by hand.&lt;/p&gt;

&lt;h2&gt;Relocating the True Cost (and Closing the Loop)&lt;/h2&gt;

&lt;p&gt;To be clear: this isn&#39;t about beating up on application developers.&lt;/p&gt;

&lt;p&gt;When a developer drops a JSON column into a migration, they aren&#39;t trying to sabotage the company. They are responding to very real, very rational pressures: sprint deadlines, velocity metrics, and avoiding the friction of formal schema reviews. From their seat in the sprint, skipping the table design feels like pure efficiency.&lt;/p&gt;

&lt;p&gt;Years ago, &lt;a href=&quot;https://carymillsap.blogspot.com/2016/05/messed-up-app-of-day-tables-of-numbers.html&quot;&gt;Cary Millsap wrote a post&lt;/a&gt; about formatting tables of numbers that contained an insight I have quoted many times:&lt;/p&gt;

&lt;div class=&quot;documentation&quot; style=&quot;background-color: #f9f9f9; border-left: 4px solid #ccc; margin: 1.5em 10px; padding: 0.5em 10px;&quot;&gt;
  &lt;p&gt;&lt;em&gt;&quot;Good design is a topic of consideration. And even conservation. If spending 10 extra minutes formatting your data better saves 1,000 readers 2 minutes each, then you’ve saved the world 1,990 minutes of wasted effort.&quot;&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Cary&#39;s math is irrefutable, but appealing to civic virtue (&quot;save the world 1,990 minutes&quot;) rarely changes engineering behavior on its own. What actually changes behavior is seeing the feedback loop close.&lt;/p&gt;

&lt;p&gt;When you dump a raw, shapeless JSON blob into a table, you didn&#39;t eliminate the work. You simply relocated the cost.&lt;/p&gt;

&lt;p&gt;In the short term, you quietly transferred that cost downstream to the analytics engineers and BI developers. Every single report now requires defensive SQL: unnesting arrays, casting strings to integers, guessing at nulls, and handling three different key spellings.&lt;/p&gt;

&lt;p&gt;But the loop doesn&#39;t stop with the analytics team.&lt;/p&gt;

&lt;p&gt;Eventually, product asks for a new operational feature: an in-app filter, a bulk edit, or a performance dashboard built directly against that transactional table. And guess who gets assigned the ticket? The application developer.&lt;/p&gt;

&lt;p&gt;Now, the very engineer who bypassed the schema to save twenty minutes in sprint four is staring at a production bug in sprint twelve, trying to write unreadable JSON path queries against their own shapeless blob. You didn&#39;t save time. You just deferred the agony, with interest, back onto your future self.&lt;/p&gt;

&lt;h2&gt;The Waiver&lt;/h2&gt;

&lt;p&gt;In my own agent instructions, a JSON column requires a waiver: the default answer is no, and the burden of proof is on the column.&lt;/p&gt;

&lt;p&gt;When does it actually earn that waiver?&lt;/p&gt;

&lt;p&gt;When the data is genuinely an opaque, third-party black box that the database never needs to reason about: raw webhook payloads, audit logs, or configuration blobs that the engine will never filter, join, or aggregate on.&lt;/p&gt;

&lt;p&gt;If your application needs to query it, if your business needs to report on it, or if it relates to any other entity in your system: it belongs in a column.&lt;/p&gt;

&lt;p&gt;Doh. It really is that simple.&lt;/p&gt;

&lt;div style=&#39;clear: both;&#39;&gt;&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/2332575659390405204/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/2332575659390405204' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/2332575659390405204'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/2332575659390405204'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2026/09/every-json-column-has-schema.html' title=' Every JSON Column Has a Schema'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-8604436845977960550</id><published>2026-09-11T21:31:33.543-04:00</published><updated>2026-09-27T11:43:46.631-04:00</updated><title type='text'>The Boolean is Still Lying to You: The OLTP Edition</title><content type='html'>&lt;p&gt;&lt;em&gt;The arguments are mine. The typing was not.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let&#39;s get straight to the point (again): &lt;strong&gt;a boolean should never be your first move in a physical data model.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Last week, in &lt;a href=&quot;https://www.oraclenerd.com/2026/09/the-boolean-is-lying-to-you.html&quot;&gt;The Boolean is Lying to You&lt;/a&gt;, we talked about how a boolean could ruin an OLAP dimensional model. In the warehouse, the problem with a boolean is that it &lt;strong&gt;duplicates&lt;/strong&gt; a truth that already exists elsewhere (temporal boundaries).&lt;/p&gt;

&lt;p&gt;But the temptation of the boolean doesn&#39;t vanish when you switch to an OLTP system. In a transactional database, the problem is the exact opposite: it &lt;strong&gt;destroys&lt;/strong&gt; a richer truth and replaces it with a poorer one.&lt;/p&gt;

&lt;p&gt;If anything, the drive for immediate application convenience has made it worse. You need to know if a user account is active, if a record is deleted, or if an order is shipped. The developer reflex is to slap an &lt;code&gt;is_active&lt;/code&gt;, &lt;code&gt;is_deleted&lt;/code&gt;, or &lt;code&gt;is_shipped&lt;/code&gt; flag on the table.&lt;/p&gt;

&lt;p&gt;Just like in the warehouse, the boolean is lying to you. In an operational system, lost fidelity means lost business context.&lt;/p&gt;

&lt;h2&gt;The &lt;code&gt;is_deleted&lt;/code&gt; Tragedy: Timestamp Trumps Boolean&lt;/h2&gt;

&lt;p&gt;The most common offender is the soft delete: &lt;code&gt;is_deleted = true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It seems harmless. The application filters out &lt;code&gt;WHERE is_deleted = false&lt;/code&gt;, and your data is &quot;safe&quot;. But in an operational system, knowing &lt;em&gt;that&lt;/em&gt; something was deleted is rarely enough. Within weeks, the business will ask: &lt;em&gt;When&lt;/em&gt; was it deleted? &lt;em&gt;Who&lt;/em&gt; deleted it? &lt;em&gt;How long&lt;/em&gt; was it active before it was removed?&lt;/p&gt;

&lt;p&gt;Your boolean is mute. It destroyed the temporal context of the event.&lt;/p&gt;

&lt;p&gt;Instead of &lt;code&gt;is_deleted&lt;/code&gt;, your first instinct should be a &lt;code&gt;deleted_at&lt;/code&gt; timestamp. If &lt;code&gt;deleted_at IS NULL&lt;/code&gt;, the record is active. If it&#39;s populated, you know exactly when the state changed. The application&#39;s &lt;code&gt;WHERE&lt;/code&gt; clause is just as simple, but the database retains the full fidelity of the event.&lt;/p&gt;

&lt;h2&gt;The Boolean Pile-Up: Where State Machines Go to Die&lt;/h2&gt;

&lt;p&gt;Business processes are rarely binary. They are lifecycles. They are state machines. But the path of least resistance often leads to modeling these state machines as a pile of mutually exclusive booleans.&lt;/p&gt;

&lt;p&gt;It starts innocently with &lt;code&gt;is_draft = true&lt;/code&gt;.&lt;br&gt;
Then the business process evolves, so we add &lt;code&gt;is_published&lt;/code&gt;.&lt;br&gt;
Then we need to pull it down temporarily, so we add &lt;code&gt;is_archived&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now you have a record where &lt;code&gt;is_draft = true&lt;/code&gt; AND &lt;code&gt;is_published = true&lt;/code&gt;. What does that mean? It means your application allowed an invalid state because your physical model didn&#39;t enforce mutual exclusivity. You forced the application code to manage the integrity of the state machine, and eventually, the code will fail.&lt;/p&gt;

&lt;p&gt;If a record moves through a lifecycle, use a &lt;code&gt;status_code&lt;/code&gt; (backed by a reference table) or an event-sourced ledger. A single &lt;code&gt;status&lt;/code&gt; column makes mutually exclusive states explicit and enforceable. Booleans just allow for combinatorial explosions of invalid states.&lt;/p&gt;

&lt;h2&gt;The Tri-State Lie&lt;/h2&gt;

&lt;p&gt;A boolean promises two states: True or False.&lt;br&gt;
But in a SQL database, a nullable boolean actually has three states: True, False, and &lt;code&gt;NULL&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What does a &lt;code&gt;NULL&lt;/code&gt; boolean mean in your application? Does it mean &quot;False&quot;? Does it mean &quot;Unknown&quot;? Does it mean &quot;Not Applicable&quot;? When &lt;code&gt;is_verified&lt;/code&gt; is NULL, did the verification fail, or has it just not happened yet?&lt;/p&gt;

&lt;p&gt;When you use a boolean to represent business state, you inevitably back yourself into relying on this ambiguous third state. If you have three states, you don&#39;t have a boolean. You have a poorly labeled lookup table.&lt;/p&gt;

&lt;h2&gt;The Indexing Bonus: The Nerd Special&lt;/h2&gt;

&lt;p&gt;There&#39;s a physical performance argument here, regardless of which database engine you use.&lt;/p&gt;

&lt;p&gt;Let&#39;s say you have a transaction processing table, and you use &lt;code&gt;is_processed = false&lt;/code&gt; to find work that needs to be done. If you index that boolean, you&#39;re indexing the entire table.&lt;/p&gt;

&lt;p&gt;Instead, if you use a &lt;code&gt;processed_at&lt;/code&gt; timestamp, you get a massive performance feature for free by using a partial (or sparse) index.&lt;/p&gt;

&lt;p&gt;By creating an index specifically for the rows &lt;code&gt;WHERE processed_at IS NULL&lt;/code&gt;, your index &lt;em&gt;only&lt;/em&gt; contains the tiny fraction of records that actually need processing. It stays perfectly sparse, incredibly small, and lightning fast. A generic boolean flag robs you of this elegant optimization.&lt;/p&gt;

&lt;h2&gt;Downstream Devastation: Why the Warehouse Cares&lt;/h2&gt;

&lt;p&gt;It’s tempting to think that an OLTP shortcut only affects the application layer. But the damage flows downstream. When you overwrite a state with a simple boolean flag, you aren&#39;t just making a lazy choice for the transactional app—you are permanently destroying data that your analytical systems desperately need.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Transitions are destroyed.&lt;/strong&gt; If you just update &lt;code&gt;is_converted = true&lt;/code&gt; or &lt;code&gt;is_canceled = true&lt;/code&gt;, you only know the final outcome. You lose the sequence of events. You can no longer calculate the duration between states, identify bottlenecks, track SLAs, or analyze churn. Operational analysis, process mining, and machine learning all require transitions to figure out &lt;em&gt;why&lt;/em&gt; something happened. A boolean destroys the transition and leaves you with a tombstone.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Time-Travel and CDC (Change Data Capture).&lt;/strong&gt; When your OLTP system relies on event logs, timestamps, or explicit status histories, extracting that data into your OLAP environment is deterministic and robust. You can perfectly reconstruct what the business looked like at any given second. If you rely on flipping a boolean in place, you force the warehouse to frantically poll and capture those fleeting changes before they are overwritten again, inevitably missing rapid transitions.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkCkYazwhwF1d-frgS3N4kZwFgdXdeLy0C0HPI61riXPPN8XB1y4egSad6SCQhTsVSmiwvQPr8NBfROInIz_QD2dECayHAB1GWUKriVJ4XIwL2OdWHgNA1gLWvwChsEZsKxM50lElMS97yiR58ZXqShHLWWr8aAJIEc0S-T9KgRF6rLv7998lY2bV_fO0/s673/booleans_in_oltp.jpg&quot; style=&quot;display: block; padding: 1em 0;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;320&quot; data-original-height=&quot;673&quot; data-original-width=&quot;500&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkCkYazwhwF1d-frgS3N4kZwFgdXdeLy0C0HPI61riXPPN8XB1y4egSad6SCQhTsVSmiwvQPr8NBfROInIz_QD2dECayHAB1GWUKriVJ4XIwL2OdWHgNA1gLWvwChsEZsKxM50lElMS97yiR58ZXqShHLWWr8aAJIEc0S-T9KgRF6rLv7998lY2bV_fO0/s320/booleans_in_oltp.jpg&quot;/&gt;&lt;/a&gt;&lt;/div&gt;

&lt;h2&gt;Stop Hiding the Business Process&lt;/h2&gt;

&lt;p&gt;In OLTP, the database is the engine of the business. When you reduce a business event (like a cancellation, a deletion, or a publication) to a boolean flag, you are erasing the context of that event. You are optimizing for a temporary application shortcut instead of modeling the reality of the domain.&lt;/p&gt;

&lt;p&gt;Just like in dimensional modeling, the rule stands: a boolean requires a waiver. Don&#39;t reach for it just because it&#39;s easy. Force yourself to ask: &lt;em&gt;&quot;Does this state have a history? Does it have a timeline? Is it part of a larger lifecycle?&quot;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Almost every time, the answer is yes. And almost every time, the boolean is the wrong move.&lt;/p&gt;

&lt;div style=&#39;clear: both;&#39;&gt;&lt;/div&gt;


&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/8604436845977960550/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/8604436845977960550' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/8604436845977960550'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/8604436845977960550'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2026/09/the-boolean-is-still-lying-to-you-oltp.html' title='The Boolean is Still Lying to You: The OLTP Edition'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkCkYazwhwF1d-frgS3N4kZwFgdXdeLy0C0HPI61riXPPN8XB1y4egSad6SCQhTsVSmiwvQPr8NBfROInIz_QD2dECayHAB1GWUKriVJ4XIwL2OdWHgNA1gLWvwChsEZsKxM50lElMS97yiR58ZXqShHLWWr8aAJIEc0S-T9KgRF6rLv7998lY2bV_fO0/s72-c/booleans_in_oltp.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-1153775159294449371</id><published>2026-09-06T14:41:11.248-04:00</published><updated>2026-09-27T11:43:59.662-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="design"/><category scheme="http://www.blogger.com/atom/ns#" term="modeling"/><title type='text'>The Boolean is Lying to You</title><content type='html'>&lt;p&gt;&lt;em&gt;The arguments are mine. The typing was not.&lt;/em&gt;&lt;/p&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
      &lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjebEu45WZy2qcjLg3K8xqglH2oQ8pDV8SR_BJ8X_megQWvWyv1GJr6UdB0i0IXUooqUngD6Lg8K91tfiz9NvvLwrhMdz-_oUK1XeXIYNyNCb_Le0il1oiN6SDd4Ghy-Dt6_0K98wpkS1eVd19EWVE0X-lbkI6EghmEYf9CWXAVT0ZZlU5oRByDsm6LEjQ/s320/is_active_boolean.jpg&quot; style=&quot;display: block; margin-bottom: 1em; padding: 1em 0px;&quot;&gt;
        &lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;559&quot; data-original-width=&quot;500&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjebEu45WZy2qcjLg3K8xqglH2oQ8pDV8SR_BJ8X_megQWvWyv1GJr6UdB0i0IXUooqUngD6Lg8K91tfiz9NvvLwrhMdz-_oUK1XeXIYNyNCb_Le0il1oiN6SDd4Ghy-Dt6_0K98wpkS1eVd19EWVE0X-lbkI6EghmEYf9CWXAVT0ZZlU5oRByDsm6LEjQ/s320/is_active_boolean.jpg&quot; /&gt;
      &lt;/a&gt;
    &lt;/div&gt;

&lt;p&gt;Let&#39;s get straight to the point: &lt;strong&gt;a boolean should never be your first move in a physical data model.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I know, I know. It&#39;s incredibly tempting. You&#39;re building a dimension table, you need to know if a row is the current one, so you slap an &lt;code&gt;is_current&lt;/code&gt; flag on the end of the script and call it a day. It feels clean. It feels simple.&lt;/p&gt;

&lt;p&gt;I&#39;m not saying a boolean is never justified. There are cases where an attribute really is just true or false, no history, no drift, no reason code required. But that case has to be earned, not assumed. In my own agent instructions, a boolean (same as jsonb) requires a waiver before it&#39;s allowed into a physical model: a deliberate, written justification, not a shortcut reached for because the alternative required more thought. The default posture is no, and the burden of proof sits on the column, not on the reviewer.&lt;/p&gt;

&lt;p&gt;Nowhere does a lazy boolean cost you more than in a dimensional model.&lt;/p&gt;

&lt;h2&gt;The OLAP Failure: Redundancy&lt;/h2&gt;

&lt;p&gt;If you have a perfectly modeled dimension table using a Slowly Changing Dimension (SCD Type 2), tracking a physical &lt;code&gt;is_current&lt;/code&gt; boolean alongside it is fundamentally redundant.&lt;/p&gt;

&lt;p&gt;The truth of whether a record is the current version at a given moment is already perfectly contained within your temporal boundaries (&lt;code&gt;valid_from&lt;/code&gt; and &lt;code&gt;valid_to&lt;/code&gt;). Adding a physical boolean flag right next to those dates introduces the very real risk of data anomalies where the flag eventually drifts out of sync with the timestamps: an ETL job dies halfway through, and now &lt;code&gt;is_current = true&lt;/code&gt; on a row whose &lt;code&gt;valid_to&lt;/code&gt; says otherwise.&lt;/p&gt;

&lt;p&gt;In a strict physical model, you store only the primary source of truth: the explicit temporal versioning columns. No independently maintained derivation sits next to them.&lt;/p&gt;

&lt;h2&gt;The &quot;Bit Bucket&quot; Trade-off&lt;/h2&gt;

&lt;p&gt;Inevitably, someone building a dashboard on top of that dimension will push back:&lt;/p&gt;

&lt;div class=&quot;documentation&quot;&gt;
&lt;p&gt;&lt;em&gt;&quot;Every consumer has to remember how this dimension represents the current row. Just give us an &lt;code&gt;is_current&lt;/code&gt; flag so every report uses the same simple predicate.&quot;&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;I understand the argument. But this is the same divide I wrote about back in 2008 and 2010: the database is not a Bit Bucket that exists to mirror the current report&#39;s WHERE clause. The physical model exists to be the single source of truth first, and convenient for one consumer second.&lt;/p&gt;

&lt;p&gt;If the derivation is genuinely a performance problem, use a materialized view, a semantic-layer cache, or a generated expression that cannot drift independently from the temporal source of truth, not a physical flag sitting next to the dates it duplicates and can silently disagree with.&lt;/p&gt;

&lt;h2&gt;&quot;But it makes it easier for the analysts!&quot;&lt;/h2&gt;

&lt;p&gt;Inevitably, whenever I make this argument, someone across the table will push back: &lt;em&gt;&quot;But having an &lt;code&gt;is_current&lt;/code&gt; flag just makes it easier for the analysts!&quot;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Every single time I hear that, I cringe. The phrase that immediately comes to mind is &quot;the soft bigotry of low expectations.&quot;&lt;/p&gt;

&lt;p&gt;Are we really going to permanently cripple our physical data model and introduce risk of out-of-sync data anomalies because we assume an analyst is incapable of writing a &lt;code&gt;WHERE valid_to IS NULL&lt;/code&gt; clause? Analysts are smart. They understand temporal data. Dumbing down the physical schema because we assume they can&#39;t handle reality is insulting to them, and dangerous for the database.&lt;/p&gt;

&lt;h2&gt;The Semantic Layer: Where Booleans Actually Belong&lt;/h2&gt;

&lt;p&gt;Don&#39;t get me wrong: while a raw boolean is a terrible way to &lt;em&gt;store&lt;/em&gt; state, it remains a genuinely useful way for a human or a BI tool to &lt;em&gt;consume&lt;/em&gt; it. End users love a good checkbox on a dashboard.&lt;/p&gt;

&lt;p&gt;That&#39;s exactly what the semantic layer is for: abstracting complex, high-fidelity underlying reality into a simple, ephemeral business definition. Your semantic layer exposes a calculated &lt;code&gt;Is Current Version&lt;/code&gt; dimension that evaluates &lt;code&gt;valid_to IS NULL&lt;/code&gt; (or your system&#39;s max-date sentinel) on the fly, at query time, against the one column that&#39;s actually the source of truth.&lt;/p&gt;

&lt;h2&gt;The Idealistic Layer Boundary&lt;/h2&gt;

&lt;p&gt;If you want a physical record that never loses temporal precision or suffers from redundant flag logic, here&#39;s the boundary between physical schema and semantic abstraction:&lt;/p&gt;

&lt;table border=&quot;1&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse: collapse; width: 100%;&quot;&gt;
  &lt;thead&gt;
    &lt;tr style=&quot;background-color: #f2f2f2;&quot;&gt;
      &lt;th style=&quot;text-align: left;&quot;&gt;Modeling Challenge&lt;/th&gt;
      &lt;th style=&quot;text-align: left;&quot;&gt;The Purist Physical Reality&lt;/th&gt;
      &lt;th style=&quot;text-align: left;&quot;&gt;The Semantic Abstraction&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;State Evaluation&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Temporal boundaries (&lt;code&gt;valid_from&lt;/code&gt; to &lt;code&gt;valid_to&lt;/code&gt;).&lt;/td&gt;
      &lt;td&gt;Ephemeral &lt;code&gt;True&lt;/code&gt;/&lt;code&gt;False&lt;/code&gt; flag calculated on the fly for dashboard filtering.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Data Integrity&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Enforced by the temporal columns themselves, single source of truth.&lt;/td&gt;
      &lt;td&gt;Enforced by a standardized definition applied consistently across every downstream BI tool.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;br&gt;
&lt;p&gt;By keeping the boolean entirely out of the physical schema and entirely inside the semantic layer, you get the best of both worlds.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;References&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.oraclenerd.com/2008/02/application-developers-vs-database.html&quot;&gt;Application Developers vs Database Developers (Part I)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.oraclenerd.com/2008/12/application-developers-vs-database.html&quot;&gt;Application Developers vs. Database Developers: Part II&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.oraclenerd.com/2010/03/database-is-bit-bucket-mentality.html&quot;&gt;The &quot;Database is a Bit Bucket&quot; Mentality&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.oraclenerd.com/2010/03/case-for-bit-bucket.html&quot;&gt;The Case for the Bit Bucket&lt;/a&gt; (by Michael Cohen)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.oraclenerd.com/2010/03/everything-is-bit-bucket.html&quot;&gt;Everything is a Bit Bucket&lt;/a&gt; (by Michael O&#39;Neill)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.oraclenerd.com/2009/03/capturing-record-history.html&quot;&gt;Capturing Record History&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/1153775159294449371/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/1153775159294449371' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/1153775159294449371'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/1153775159294449371'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2026/09/the-boolean-is-lying-to-you.html' title='The Boolean is Lying to You'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjebEu45WZy2qcjLg3K8xqglH2oQ8pDV8SR_BJ8X_megQWvWyv1GJr6UdB0i0IXUooqUngD6Lg8K91tfiz9NvvLwrhMdz-_oUK1XeXIYNyNCb_Le0il1oiN6SDd4Ghy-Dt6_0K98wpkS1eVd19EWVE0X-lbkI6EghmEYf9CWXAVT0ZZlU5oRByDsm6LEjQ/s72-c/is_active_boolean.jpg" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-3709968278156580565</id><published>2026-08-22T16:49:01.709-04:00</published><updated>2026-09-27T11:44:09.609-04:00</updated><title type='text'>How to Answer Questions the Smart Way</title><content type='html'>&lt;p&gt;&lt;em&gt;The arguments are mine. The typing was not.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;For years, one of the top recommendations on my &lt;a href=&quot;https://www.oraclenerd.com/2013/06/required-reading.html&quot;&gt;Required Reading&lt;/a&gt; list has been Eric S. Raymond&#39;s classic essay, &lt;a href=&quot;http://www.catb.org/~esr/faqs/smart-questions.html&quot;&gt;&lt;em&gt;How to Ask Questions the Smart Way&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I still recommend it. It is a foundational text on respecting other people&#39;s cognitive load. Do your homework, provide context, state the problem clearly, and make it easy for the person helping you.&lt;/p&gt;

&lt;p&gt;And it is not the only one. The industry has spent two decades obsessing over this exact friction:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Project Maintainer&#39;s View&lt;/strong&gt;: In his book &lt;a href=&quot;https://producingoss.com/&quot;&gt;&lt;em&gt;Producing Open Source Software&lt;/em&gt;&lt;/a&gt;, Karl Fogel dedicates an entire section to handling newbie questions constructively. He popularized the ethos that even if you have seen a question 1,000 times, it is that specific user&#39;s first time asking it, making a helpful response a critical investment in community goodwill.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The &quot;Imagine You&#39;re Answering&quot; Framework&lt;/strong&gt;: Developer Jon Skeet wrote a highly cited piece on &lt;a href=&quot;https://codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question/&quot;&gt;&lt;em&gt;Writing the Perfect Question&lt;/em&gt;&lt;/a&gt;. While technically a guide for askers, it flips the script by forcing the writer to completely adopt the mindset, limitations, and frustrations of the responder before hitting submit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Defensive Programming Analogy&lt;/strong&gt;: Jeff Atwood of Coding Horror frequently blogged about the friction between askers and answerers, most notably in &lt;a href=&quot;https://blog.codinghorror.com/dont-ask-us-questions-well-just-ignore-you/&quot;&gt;&lt;em&gt;Don&#39;t Ask Us Questions, We&#39;ll Just Ignore You&lt;/em&gt;&lt;/a&gt;. His commentary focuses on how community systems (like Stack Overflow) must be architected to filter out noise so experts don&#39;t burn out and become toxic.&lt;/p&gt;

&lt;p&gt;These are all brilliant pieces of writing. But after a couple of decades working across architecture, operations, and data engineering, I&#39;ve realized something. We spend a massive amount of time teaching engineers how to ask better questions. We spend almost zero time teaching experts how to answer them.&lt;/p&gt;

&lt;p&gt;I&#39;ve made this mistake myself. But regardless of who is doing it, the truth remains: a lot of the communication failures I see aren&#39;t caused by bad questions. They are caused by bad answers.&lt;/p&gt;

&lt;p&gt;The core problem is usually this: The asker is trying to establish the model. The responder is answering with implementation details, caveats, and breadcrumbs.&lt;/p&gt;



&lt;h2&gt;The Excavation&lt;/h2&gt;

&lt;p&gt;We have all witnessed, or participated in, this exact pattern:&lt;/p&gt;

&lt;div class=&quot;documentation&quot;&gt;
&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt; Does feature X do Y by default?&lt;br&gt;
&lt;strong&gt;Answer:&lt;/strong&gt; Well, it can be configured differently depending on the deployment.&lt;br&gt;
&lt;strong&gt;Question:&lt;/strong&gt; Right, but out of the box, does it do Y?&lt;br&gt;
&lt;strong&gt;Answer:&lt;/strong&gt; Administrators can change the setting to do Z instead.&lt;br&gt;
&lt;strong&gt;Question:&lt;/strong&gt; Okay, but if I just turn it on without changing anything, what happens?&lt;br&gt;
&lt;strong&gt;Answer:&lt;/strong&gt; Yes, it defaults to Y.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;What follows is an excavation. The asker has to carefully dig through three or four rounds of follow-ups just to extract a simple fact.&lt;/p&gt;

&lt;p&gt;If it takes twenty minutes and a half-dozen replies to get a one-sentence answer, the problem was not the question. The question was fine. The failure was in the information transfer.&lt;/p&gt;

&lt;h2&gt;The Expert&#39;s Burden&lt;/h2&gt;

&lt;p&gt;ESR&#39;s essay is fundamentally about reducing the cost imposed on the answerer. But there is a reciprocal obligation. If you are the expert, the owner, or the authority, you owe clarity to the asker.&lt;/p&gt;

&lt;p&gt;I understand &lt;em&gt;why&lt;/em&gt; this happens. It is usually a defensive mechanism. We front-load the caveats because we are terrified of being technically &quot;wrong&quot; or called out over some obscure edge case. We want to protect ourselves by dumping all our context onto the table at once.&lt;/p&gt;

&lt;p&gt;But the obligation to respect someone else&#39;s time does not end when they finish asking the question.&lt;/p&gt;

&lt;div class=&quot;documentation&quot;&gt;&lt;p&gt;A good answer reduces uncertainty. It shrinks the search space. A bad answer expands it.&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;If the audience still has the same question after you respond, you haven&#39;t helped them. You have just transferred your cognitive load onto them, forcing them to reconstruct your intent.&lt;/p&gt;

&lt;p&gt;It is very similar to the problem with passive voice (something &lt;a href=&quot;https://carymillsap.com/&quot;&gt;Cary Millsap&lt;/a&gt; has talked about for years). The real sin of passive voice isn&#39;t grammar. It is making the reader work to reconstruct causality.&lt;/p&gt;

&lt;p&gt;Poor technical answers create the same problem. The audience must reconstruct the model, the assumptions, and the contract from fragments scattered across multiple replies.&lt;/p&gt;

&lt;h2&gt;Answer Like an API&lt;/h2&gt;

&lt;p&gt;Answering questions effectively is an architecture skill.&lt;/p&gt;

&lt;p&gt;A systems person naturally thinks in contracts. What is the source of truth? What guarantees does the system make? What is the documented behavior? Everything else is just plumbing.&lt;/p&gt;

&lt;p&gt;We need to treat our answers the exact same way. When someone asks a question, they are usually looking for the contract.&lt;/p&gt;

&lt;p&gt;Experts often begin with caveats, history, edge cases, implementation details, and exceptions. Resist that urge.&lt;/p&gt;

&lt;div class=&quot;documentation&quot;&gt;&lt;p&gt;The answer goes first. Everything else is commentary.&lt;/p&gt;&lt;/div&gt;

&lt;div class=&quot;documentation&quot;&gt;
&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt; Does feature X do Y by default?&lt;br&gt;
&lt;strong&gt;Better Answer:&lt;/strong&gt; Yes, it defaults to Y out of the box. The configuration option allows you to override this behavior. Here is the link to the doc.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Experts often answer in chronological order (&quot;Here is the history, here are the caveats, therefore the answer is X&quot;). Good communicators answer in logical order (&quot;The answer is X, here is why, here are the caveats&quot;).&lt;/p&gt;

&lt;p&gt;It is the Minto Principle applied to engineering. The answer should be the first sentence, not the last.&lt;/p&gt;

&lt;h2&gt;Reduce Ambiguity&lt;/h2&gt;

&lt;p&gt;The same instinct that drives us toward explicit schemas, API definitions, and data contracts should drive our communication. Make the model explicit. Put the definition where everyone can see it.&lt;/p&gt;

&lt;p&gt;The purpose of an answer is not to display expertise. The purpose of an answer is to transfer understanding.&lt;/p&gt;

&lt;p&gt;Good architecture, documentation, and APIs all do one thing: they reduce ambiguity. Good answers should do the exact same.&lt;/p&gt;

&lt;div class=&quot;documentation&quot;&gt;&lt;p&gt;Don&#39;t make people pull teeth to understand the system.&lt;/p&gt;&lt;/div&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
  &lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEi9lL0i2bl01tK6Wn4-PYxYmAy1tAn0PZAT7j1hZy1TwLG9Paf3Ag6G2rPOfyoGgtOhS3D2PBu0KcnWuREJ8KxMwlNTwFE8Ng56E_MAX3e3O8kfgP8bX6nrAs3Y4ri8W8fEbaKWRKKrlUL7GqhXUtFhjoaPjlUtlRNGWYqY7BWFVFHdet14c3zB9NKRZ1w&quot; style=&quot;margin-bottom: 1em;&quot;&gt;
    &lt;img alt=&quot;&quot; data-original-height=&quot;509&quot; data-original-width=&quot;462&quot; height=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEi9lL0i2bl01tK6Wn4-PYxYmAy1tAn0PZAT7j1hZy1TwLG9Paf3Ag6G2rPOfyoGgtOhS3D2PBu0KcnWuREJ8KxMwlNTwFE8Ng56E_MAX3e3O8kfgP8bX6nrAs3Y4ri8W8fEbaKWRKKrlUL7GqhXUtFhjoaPjlUtlRNGWYqY7BWFVFHdet14c3zB9NKRZ1w=w182-h200&quot; width=&quot;182&quot; /&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/3709968278156580565/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/3709968278156580565' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/3709968278156580565'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/3709968278156580565'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2026/08/how-to-answer-questions-smart-way.html' title='How to Answer Questions the Smart Way'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/a/AVvXsEi9lL0i2bl01tK6Wn4-PYxYmAy1tAn0PZAT7j1hZy1TwLG9Paf3Ag6G2rPOfyoGgtOhS3D2PBu0KcnWuREJ8KxMwlNTwFE8Ng56E_MAX3e3O8kfgP8bX6nrAs3Y4ri8W8fEbaKWRKKrlUL7GqhXUtFhjoaPjlUtlRNGWYqY7BWFVFHdet14c3zB9NKRZ1w=s72-w182-h200-c" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-6125325896418337525</id><published>2026-05-17T22:35:59.799-04:00</published><updated>2026-09-27T11:44:30.801-04:00</updated><title type='text'>You Can Point a Foreign Key Where?!</title><content type='html'>&lt;p&gt;&lt;i&gt;Editor&#39;s Note: The arguments are mine. The typing was not.&lt;/i&gt;&lt;/p&gt;&lt;p&gt;Let’s talk about things we &lt;i data-index-in-node=&quot;27&quot; data-path-to-node=&quot;3&quot;&gt;think&lt;/i&gt; we know, but it turns out we’ve (read: &lt;b&gt;me&lt;/b&gt;) just been following muscle memory for twenty-plus years.&lt;/p&gt;&lt;p data-path-to-node=&quot;4&quot;&gt;If you asked me on any given Tuesday what a foreign key does, I’d give you the standard textbook answer. It points to the primary key of a parent table. It’s bread-and-butter relational modeling. We back it with a sequence or an identity column, we join on the IDs, and we move on with our lives.&lt;/p&gt;&lt;p data-path-to-node=&quot;5&quot;&gt;But a funny thing happened on the way to the database the other day. I realized, or rather, I was reminded, that the SQL standard and Oracle Database don’t actually care about your primary key.&lt;/p&gt;&lt;p data-path-to-node=&quot;6&quot;&gt;A foreign key doesn&#39;t &lt;i&gt;have&lt;/i&gt; to reference a &lt;code data-index-in-node=&quot;42&quot; data-path-to-node=&quot;6&quot;&gt;PRIMARY KEY&lt;/code&gt;. It just needs to reference a &lt;b data-index-in-node=&quot;84&quot; data-path-to-node=&quot;6&quot;&gt;minimal unique identifier&lt;/b&gt;. That means any column set with a valid &lt;code data-index-in-node=&quot;150&quot; data-path-to-node=&quot;6&quot;&gt;UNIQUE&lt;/code&gt; constraint is fair game.&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2tv9Fs6wk1Ma24c9PFoPZRaCDMIxLAvZEp1G2dJ4J3OqZLTbejQWZY2kO-xmgrsFBZVRBwcuNo0xfp8VtN9YjFg5S0twASezO_VG_emtfCP9svbvX_i_ICiNEdOzRwUKTwFENWkGT3HrjBOaXL8RC_8XKFT8ZZO3PFcu90SoL0EOSmn28P8oAo_OD2kk/s500/giphy.gif&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;500&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2tv9Fs6wk1Ma24c9PFoPZRaCDMIxLAvZEp1G2dJ4J3OqZLTbejQWZY2kO-xmgrsFBZVRBwcuNo0xfp8VtN9YjFg5S0twASezO_VG_emtfCP9svbvX_i_ICiNEdOzRwUKTwFENWkGT3HrjBOaXL8RC_8XKFT8ZZO3PFcu90SoL0EOSmn28P8oAo_OD2kk/w320-h320/giphy.gif&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p data-path-to-node=&quot;6&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;h3 data-path-to-node=&quot;7&quot;&gt;&lt;br /&gt;&lt;/h3&gt;&lt;h3 data-path-to-node=&quot;7&quot;&gt;&lt;br /&gt;&lt;/h3&gt;&lt;h3 data-path-to-node=&quot;7&quot;&gt;&lt;br /&gt;&lt;/h3&gt;&lt;h3 data-path-to-node=&quot;7&quot;&gt;&lt;br /&gt;&lt;/h3&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h3 data-path-to-node=&quot;7&quot;&gt;The Setup&lt;/h3&gt;&lt;p data-path-to-node=&quot;8&quot;&gt;Imagine you have a standard reference lookup table for order statuses. You’ve got your surrogate auto-incrementing ID as the PK because that’s what we do. But you also have an alphanumeric business code that the application actually uses, and that code is guaranteed unique.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;
CREATE TABLE order_statuses (
    status_id   NUMBER GENERATED BY DEFAULT AS IDENTITY,
    status_code VARCHAR2(10) NOT NULL,
    description VARCHAR2(100) NOT NULL,
    --
    CONSTRAINT pk_order_statuses PRIMARY KEY (status_id),
    CONSTRAINT uq_order_statuses_code UNIQUE (status_code)
);&lt;br /&gt;
&lt;/code&gt;&lt;/pre&gt;
Normally, devs will map the &lt;code&gt;status_id&lt;/code&gt; down to the child orders table. But what if you map the code instead?
&lt;pre&gt;&lt;code&gt;CREATE TABLE orders (
    order_id     NUMBER GENERATED BY DEFAULT AS IDENTITY,
    order_status VARCHAR2(10) NOT NULL,
    -- Look Ma, no status_id!
    CONSTRAINT pk_orders PRIMARY KEY (order_id),
    CONSTRAINT fk_orders_status 
        FOREIGN KEY (order_status) 
        REFERENCES order_statuses (status_code)
);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This compiles. It validates. It works.&lt;/p&gt;&lt;h3 data-path-to-node=&quot;13&quot;&gt;Why Do We Care?&lt;/h3&gt;&lt;p data-path-to-node=&quot;14&quot;&gt;If you are a &quot;data-first&quot; person, this opens up some interesting pragmatic design choices, especially for seed data and reference enums.&lt;/p&gt;&lt;ol data-path-to-node=&quot;15&quot; start=&quot;1&quot;&gt;&lt;li&gt;&lt;p data-path-to-node=&quot;15,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;15,0,0&quot;&gt;No-Join Readability:&lt;/b&gt; When I run a quick &lt;code data-index-in-node=&quot;40&quot; data-path-to-node=&quot;15,0,0&quot;&gt;SELECT * FROM orders&lt;/code&gt;, I don&#39;t see status &lt;code data-index-in-node=&quot;81&quot; data-path-to-node=&quot;15,0,0&quot;&gt;1&lt;/code&gt;, &lt;code data-index-in-node=&quot;84&quot; data-path-to-node=&quot;15,0,0&quot;&gt;2&lt;/code&gt;, or &lt;code data-index-in-node=&quot;90&quot; data-path-to-node=&quot;15,0,0&quot;&gt;3&lt;/code&gt;. I see &lt;code data-index-in-node=&quot;99&quot; data-path-to-node=&quot;15,0,0&quot;&gt;&#39;PENDING&#39;&lt;/code&gt;, &lt;code data-index-in-node=&quot;110&quot; data-path-to-node=&quot;15,0,0&quot;&gt;&#39;SHIPPED&#39;&lt;/code&gt;, or &lt;code data-index-in-node=&quot;124&quot; data-path-to-node=&quot;15,0,0&quot;&gt;&#39;CANCELLED&#39;&lt;/code&gt;. I don’t have to write an explicit &lt;code data-index-in-node=&quot;171&quot; data-path-to-node=&quot;15,0,0&quot;&gt;JOIN&lt;/code&gt; to a lookup table just to debug a row in a terminal log.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p data-path-to-node=&quot;15,1,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;15,1,0&quot;&gt;CI/CD Sanity:&lt;/b&gt; Moving seed data across Dev, QA, and Prod environments when you rely purely on surrogate sequences can be a nightmare of dynamic mapping scripts. Business codes are immutable constants across environments. Your deployment scripts can just hardcode the literals without breaking things.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h3 data-path-to-node=&quot;16&quot;&gt;The Fine Print (Because this is Oracle)&lt;/h3&gt;&lt;p data-path-to-node=&quot;17&quot;&gt;Before you go rewriting your entire data model, remember that the laws of physics still apply.&lt;/p&gt;&lt;p data-path-to-node=&quot;18&quot;&gt;First, Oracle &lt;b data-index-in-node=&quot;14&quot; data-path-to-node=&quot;18&quot;&gt;does not&lt;/b&gt; automatically index foreign keys. If you point a child table to a parent’s unique business code, and somebody tries to delete or modify that code in the parent table, Oracle has to scan the child table to ensure no orphan records are left behind. If you didn’t manually put an index on &lt;code data-index-in-node=&quot;309&quot; data-path-to-node=&quot;18&quot;&gt;orders.order_status&lt;/code&gt;, you are looking at a Full Table Scan and a nasty shared sub-exclusive table lock (&lt;code data-index-in-node=&quot;412&quot; data-path-to-node=&quot;18&quot;&gt;TM&lt;/code&gt;) that will freeze concurrent operations.&lt;/p&gt;&lt;p data-path-to-node=&quot;19&quot;&gt;Second, don&#39;t try this on your Slowly Changing Dimension (SCD) Type 2 tables. The second a business code repeats because you are tracking historical versions with effective dates, table-wide uniqueness breaks. And no, you can&#39;t use a partial function-based index to bypass this; declarative foreign keys need real, concrete constraints.&lt;/p&gt;&lt;h3 data-path-to-node=&quot;20&quot;&gt;Relational Reality Check&lt;/h3&gt;&lt;p data-path-to-node=&quot;21&quot;&gt;In relational theory, a foreign key references a candidate key, which is simply a minimal superkey. The choice to elevate one candidate key to be the &quot;Primary Key&quot; is a physical implementation choice, not a logical requirement.&lt;/p&gt;&lt;p data-path-to-node=&quot;22&quot;&gt;It’s completely valid, ANSI-standard behavior. It’s supported in Postgres and SQL Server too, so it’s not just an Oracle quirk.&lt;/p&gt;&lt;p data-path-to-node=&quot;23&quot;&gt;It&#39;s just one of those elegant database features hiding in plain sight while application layers spend thousands of lines of code trying to reinvent referential integrity.&lt;/p&gt;&lt;p data-path-to-node=&quot;24&quot;&gt;Keep it in the database.&lt;/p&gt;&lt;h3 data-path-to-node=&quot;26&quot;&gt;Appendix: Documentation &amp;amp; Structural Foundations&lt;/h3&gt;&lt;h4 data-path-to-node=&quot;27&quot;&gt;Oracle Database Documentation&lt;/h4&gt;&lt;ul data-path-to-node=&quot;28&quot;&gt;&lt;li&gt;&lt;p data-path-to-node=&quot;28,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;28,0,0&quot;&gt;Oracle SQL Language Reference — The &lt;code data-index-in-node=&quot;36&quot; data-path-to-node=&quot;28,0,0&quot;&gt;constraint&lt;/code&gt; Clause:&lt;/b&gt; The definitive syntax rules and structural restrictions governing referential integrity, confirming that foreign keys can target primary keys or unique constraints.&lt;/p&gt;&lt;p data-path-to-node=&quot;28,0,1&quot;&gt;&lt;response-element ng-version=&quot;0.0.0-PLACEHOLDER&quot;&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;link-block _nghost-ng-c2796740781=&quot;&quot; class=&quot;ng-star-inserted&quot;&gt;&lt;!----&gt;&lt;!----&gt;&lt;a _ngcontent-ng-c2796740781=&quot;&quot; _nghost-ng-c3313056749=&quot;&quot; class=&quot;ng-star-inserted&quot; data-hveid=&quot;0&quot; data-ved=&quot;0CAAQ_4QMahgKEwi_nfCn3cGUAxUAAAAAHQAAAAAQ5QE&quot; decode-data-ved=&quot;1&quot; externallink=&quot;&quot; href=&quot;https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/constraint.html&quot; jslog=&quot;197247;track:generic_click,impression,attention;BardVeMetadataKey:[[&amp;quot;r_fdb711d203c93a23&amp;quot;,&amp;quot;c_79d120ec871d2bf3&amp;quot;,null,&amp;quot;rc_be4a50ac9aa07d15&amp;quot;,null,null,&amp;quot;&amp;quot;,null,1,null,null,1,0]]&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;Oracle Database SQL Language Reference — Constraints&lt;/a&gt;&lt;/link-block&gt;&lt;/response-element&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h4 data-path-to-node=&quot;29&quot;&gt;Edgar F. Codd &amp;amp; Relational Theory&lt;/h4&gt;&lt;ul data-path-to-node=&quot;30&quot;&gt;&lt;li&gt;&lt;p data-path-to-node=&quot;30,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;30,0,0&quot;&gt;The 1970 Foundation Paper:&lt;/b&gt; &lt;i data-index-in-node=&quot;27&quot; data-path-to-node=&quot;30,0,0&quot;&gt;Codd, E. F. (1970). &quot;A Relational Model of Data for Large Shared Data Banks.&quot; Communications of the ACM.&lt;/i&gt; The original blueprint that introduced relational algebra, establishing that relationships are derived strictly by matching domains over mathematical relations rather than rigidly named primary/foreign key pairs.&lt;/p&gt;&lt;p data-path-to-node=&quot;30,0,1&quot;&gt;&lt;response-element ng-version=&quot;0.0.0-PLACEHOLDER&quot;&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;link-block _nghost-ng-c2796740781=&quot;&quot; class=&quot;ng-star-inserted&quot;&gt;&lt;!----&gt;&lt;!----&gt;&lt;a _ngcontent-ng-c2796740781=&quot;&quot; _nghost-ng-c3313056749=&quot;&quot; class=&quot;ng-star-inserted&quot; data-hveid=&quot;0&quot; data-ved=&quot;0CAAQ_4QMahgKEwi_nfCn3cGUAxUAAAAAHQAAAAAQ6AE&quot; decode-data-ved=&quot;1&quot; externallink=&quot;&quot; href=&quot;https://dl.acm.org/doi/10.1145/362384.362685&quot; jslog=&quot;197247;track:generic_click,impression,attention;BardVeMetadataKey:[[&amp;quot;r_fdb711d203c93a23&amp;quot;,&amp;quot;c_79d120ec871d2bf3&amp;quot;,null,&amp;quot;rc_be4a50ac9aa07d15&amp;quot;,null,null,&amp;quot;&amp;quot;,null,1,null,null,1,0]]&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;ACM Digital Library — A Relational Model of Data for Large Shared Data Banks&lt;/a&gt;&lt;!----&gt;&lt;/link-block&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;/response-element&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p data-path-to-node=&quot;30,1,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;30,1,0&quot;&gt;The Relational Model for Database Management: Version 2 (Book):&lt;/b&gt; &lt;i data-index-in-node=&quot;64&quot; data-path-to-node=&quot;30,1,0&quot;&gt;Codd, E. F. (1990). Addison-Wesley.&lt;/i&gt; Codd formalizes RM/V2, explicitly grouping Primary Keys and Alternate Keys together under the definition of Candidate Keys, proving that referential integrity mathematically depends on the candidate key property of uniqueness.&lt;/p&gt;&lt;p data-path-to-node=&quot;30,1,1&quot;&gt;&lt;response-element ng-version=&quot;0.0.0-PLACEHOLDER&quot;&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;!----&gt;&lt;link-block _nghost-ng-c2796740781=&quot;&quot; class=&quot;ng-star-inserted&quot;&gt;&lt;!----&gt;&lt;!----&gt;&lt;a _ngcontent-ng-c2796740781=&quot;&quot; _nghost-ng-c3313056749=&quot;&quot; class=&quot;ng-star-inserted&quot; data-hveid=&quot;0&quot; data-ved=&quot;0CAAQ_4QMahgKEwi_nfCn3cGUAxUAAAAAHQAAAAAQ6QE&quot; decode-data-ved=&quot;1&quot; externallink=&quot;&quot; href=&quot;https://www.google.com/search?q=https://dl.acm.org/doi/book/10.5555/78026&quot; jslog=&quot;197247;track:generic_click,impression,attention;BardVeMetadataKey:[[&amp;quot;r_fdb711d203c93a23&amp;quot;,&amp;quot;c_79d120ec871d2bf3&amp;quot;,null,&amp;quot;rc_be4a50ac9aa07d15&amp;quot;,null,null,&amp;quot;&amp;quot;,null,1,null,null,1,0]]&quot; rel=&quot;noopener&quot; target=&quot;_blank&quot;&gt;ACM Digital Library — The Relational Model for Database Management (Version 2)&lt;/a&gt;&lt;/link-block&gt;&lt;/response-element&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/6125325896418337525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/6125325896418337525' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/6125325896418337525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/6125325896418337525'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2026/05/you-can-point-foreign-key-where.html' title='You Can Point a Foreign Key Where?!'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2tv9Fs6wk1Ma24c9PFoPZRaCDMIxLAvZEp1G2dJ4J3OqZLTbejQWZY2kO-xmgrsFBZVRBwcuNo0xfp8VtN9YjFg5S0twASezO_VG_emtfCP9svbvX_i_ICiNEdOzRwUKTwFENWkGT3HrjBOaXL8RC_8XKFT8ZZO3PFcu90SoL0EOSmn28P8oAo_OD2kk/s72-w320-h320-c/giphy.gif" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-1387470483857142440</id><published>2026-05-12T08:49:00.002-04:00</published><updated>2026-05-12T09:00:10.813-04:00</updated><title type='text'>The System Works</title><content type='html'>&lt;p&gt;For the last 20 years or so I&#39;ve thought about what retirement might look like.&amp;nbsp;&lt;/p&gt;&lt;p&gt;In retirement, I&#39;d go back to school and write a thesis on... I didn&#39;t know what to call it. The &quot;Medical Industrial Complex?&quot; Much of this was due to the many, many, many interactions as it relates to &lt;a href=&quot;https://www.oraclenerd.com/search/label/kate&quot;&gt;Kate&lt;/a&gt;.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&quot;I&#39;ll go back to school, do the research, get my PhD.&quot; Mostly so I could participate in &lt;a href=&quot;https://www.imdb.com/title/tt0090056/&quot;&gt;Spies Like Us&lt;/a&gt; shenanigans:&amp;nbsp;&lt;a href=&quot;https://www.youtube.com/watch?v=hoe24aSvLtw&quot;&gt;Doctor. Doctor. Doctor. Doctor.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I had this gut feeling that something was...broken; none of it made sense.&amp;nbsp;&lt;/p&gt;&lt;p&gt;When I didn&#39;t have insurance, $115 copay. When I did have insurance, $400.&amp;nbsp;&lt;/p&gt;&lt;p&gt;As a consultant/contractor, I understood how we measure things in time; &lt;i&gt;n&lt;/i&gt; dollars/hour.&amp;nbsp;&lt;/p&gt;&lt;p&gt;OK, so Doc is $115 x 4 (because it may have been 15 minutes, I&#39;m being super generous here), how is it now $400 x 4/hour? How in the hell does handing over a piece of plastic turn a $460/hr rate into $1,600/hour?&lt;/p&gt;&lt;p&gt;I&#39;m (often) told I need a hobby. Outside of work. What many don&#39;t realize is that I&#39;m one of the fortunate ones; what I do for a living is not work.&lt;/p&gt;&lt;p&gt;Choose a job you love, and you will never have to work a day in your life. Or whatever that phrase is.&amp;nbsp;&lt;/p&gt;&lt;p&gt;So, one Sunday, a few weeks back, I set &lt;a href=&quot;https://antigravity.google/&quot;&gt;Antigravity&lt;/a&gt; (Gemini) loose on my idea. I just told it: &quot;I have an idea I want to explore.&quot;&lt;/p&gt;&lt;p&gt;I didn&#39;t expect a book. I expected a conversation. But what happened over the next few hours was the mechanical equivalent of &lt;span data-index-in-node=&quot;126&quot; data-path-to-node=&quot;7,0&quot;&gt;defining the schema for 20 years of observations.&lt;/span&gt; I threw two decades of &quot;gut feelings&quot; at the machine, and it started mapping the plumbing. Before I knew it, I had a 23-bullet outline and links to 50-75 outside sources.&lt;/p&gt;&lt;p&gt;&quot;Fully fleshed out, how long would this be?&quot;&lt;/p&gt;&lt;p&gt;&quot;350-400 pages.&quot;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKbpC-rZXEE4BhM7oiU9bczxHt7jjqQF3UdDbeFCU99xZkK4dsnh-By8mmDEjhIt8AUWxg6x9QDTAeIg0XHv5pP8F1TPTq6c7I0h3EQ-d9Dq3p5EW8AOK2NxQl4u08AxsucY-WBhsTiwnUsIHSfugIVHCNrE8zD5C_Oacxqu8syLb_CQpMlx3K6O_wM1s/s165/kermit_gulp.gif&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;135&quot; data-original-width=&quot;165&quot; height=&quot;135&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKbpC-rZXEE4BhM7oiU9bczxHt7jjqQF3UdDbeFCU99xZkK4dsnh-By8mmDEjhIt8AUWxg6x9QDTAeIg0XHv5pP8F1TPTq6c7I0h3EQ-d9Dq3p5EW8AOK2NxQl4u08AxsucY-WBhsTiwnUsIHSfugIVHCNrE8zD5C_Oacxqu8syLb_CQpMlx3K6O_wM1s/s1600/kermit_gulp.gif&quot; width=&quot;165&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&quot;OK, let&#39;s pare that back&quot;&lt;/p&gt;&lt;p&gt;Gemini proceeded to suggest serializing it on Substack or just going with an abbreviated manifesto.&lt;/p&gt;&lt;p&gt;I chose the manifesto. We pared it down to 8 dense chapters. It wrote the Intro.&amp;nbsp;&lt;/p&gt;&lt;p&gt;What...do I...OMG...this is...wow.&amp;nbsp;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;If you spend enough time listening to patients, doctors, or politicians, you will hear a single, unifying complaint spoken across every demographic and tax bracket in America:&lt;/p&gt;&lt;p&gt;The healthcare system is entirely broken.&lt;/p&gt;&lt;p&gt;It is the one rare diagnosis found across every boardroom, breakroom, and waiting room in the country. They point to the soul-crushing administrative bloat that forces practitioners into eight-minute volume appointments. They point to the labyrinthine &quot;prior authorization&quot; processes where algorithms deny life-saving treatments.&lt;/p&gt;&lt;p&gt;And yet, this frustration is born entirely from a profound paradox.&lt;/p&gt;&lt;p&gt;If you strip away the billing departments and the insurance mandates, the actual clinical engineering of the American medical system is nothing short of miraculous. If you are diagnosed with a rare leukemia, or require an unprecedented cardiothoracic intervention, there is quite literally nowhere else on earth you would rather be. The United States produces the most advanced, precision-engineered medical science in the history of human civilization. The people executing that science—the physicians, the bio-engineers, the surgical staff—are elite.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;That is &lt;i&gt;not &lt;/i&gt;the original, but you get the idea. I spent time reading and editing that introduction, changing the tone, the focus, where I ended up creating a &lt;span style=&quot;font-family: courier;&quot;&gt;GUIDING_PRINCIPLES.md&lt;/span&gt; file to keep it inline:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Dissect the Maze, Don&#39;t Indict the Mice&lt;/li&gt;&lt;li&gt;Empathy for the Inheritor&lt;/li&gt;&lt;li&gt;No Emotional Accusations, Only Systemic Mechanics&lt;/li&gt;&lt;li&gt;Labels are &quot;Pre-Written Baggage&quot;&lt;/li&gt;&lt;li&gt;Bypass Over Bureacracy&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Super cool. A few iterations later, I had an Intro. On to Chapter 1. Same process. Edit for tone and clarity, but otherwise let it loose. Chapter 2, same. After Chapter 2, I just let it rip. By the end of that Sunday session, &lt;i&gt;maybe &lt;/i&gt;5 hours, I had a 40 page &quot;book.&quot;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Over the next couple of days, I&#39;d spend 30-60 minutes creating cover and chapter art (with Gemini web).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;On Wednesday I had reached my quota for the month, the $20/month plan would reset on 4/11 (Saturday).&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I was exploring publishing options, I&#39;ve always wanted to be a published writer (as I type that, I realize there are north of 800 articles here, so...).&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But like that, that specific itch was gone. I did not revisit on Saturday. I &lt;i&gt;did &lt;/i&gt;share with friends and colleagues. I solicited feedback. I began to incorporate feedback and also track who provided what feedback.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Fast forward a month, and I came head to head with this system again. It was unpleasant to say the least.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 14px;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: 14px;&quot;&gt;&lt;span style=&quot;font-family: georgia;&quot;&gt;Now, however, I was armed with new tools. The system hadn’t changed, but I could finally see how it moved; where the paths were, and why people kept ending up in the same places.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/1387470483857142440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/1387470483857142440' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/1387470483857142440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/1387470483857142440'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2026/05/the-system-works.html' title='The System Works'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKbpC-rZXEE4BhM7oiU9bczxHt7jjqQF3UdDbeFCU99xZkK4dsnh-By8mmDEjhIt8AUWxg6x9QDTAeIg0XHv5pP8F1TPTq6c7I0h3EQ-d9Dq3p5EW8AOK2NxQl4u08AxsucY-WBhsTiwnUsIHSfugIVHCNrE8zD5C_Oacxqu8syLb_CQpMlx3K6O_wM1s/s72-c/kermit_gulp.gif" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-2874916995633862369</id><published>2026-05-02T13:10:00.002-04:00</published><updated>2026-05-05T22:33:47.815-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ai"/><title type='text'>The Death of the API Barrier: From Jargon Intimidation to Result Sets and AI</title><content type='html'>If you were a database guy in the early 2000s, APIs didn’t exactly show up with a gift basket and a smile.&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggrBhyphenhyphenq-YDxhmaZA-qsIy6eReSN6LSeOu-8LnT___LC3xpHarKNHj2dBPBpiardepnrKP_SHXb-FcsKGykr9j9V9cNF7HccJCzdK6AmG_Y6wVekKTpoCYmTsKWPjZTHW8-KjA2vsDqjJ9n11RaCZinpNwcyx-rY34uS4Er1kKdk5ZHLSukUGsom1b_I-4/s2816/oraclenerd_api_and_ai.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1536&quot; data-original-width=&quot;2816&quot; height=&quot;218&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggrBhyphenhyphenq-YDxhmaZA-qsIy6eReSN6LSeOu-8LnT___LC3xpHarKNHj2dBPBpiardepnrKP_SHXb-FcsKGykr9j9V9cNF7HccJCzdK6AmG_Y6wVekKTpoCYmTsKWPjZTHW8-KjA2vsDqjJ9n11RaCZinpNwcyx-rY34uS4Er1kKdk5ZHLSukUGsom1b_I-4/w400-h218/oraclenerd_api_and_ai.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;They showed up as these massive, scary-looking blocks of XML that people called SOAP. Or maybe it was a WSDL? Honestly, I could barely spell those acronyms, let alone tell you what they were supposed to do. I didn’t have a Computer Science degree, and looking at those files felt like I’d wandered into a high-level physics lecture by mistake.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;I was brand new to IT, and the whole &quot;web service&quot; thing was just...intimidating. It felt like a club I didn&#39;t have the password for. I didn&#39;t know how they worked, I didn&#39;t know why people liked them, and I certainly didn&#39;t want to admit I was lost. So I did what anyone does when they’re staring at something that makes them feel out of their depth: I retreated to safety.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;I stayed where things made sense. Tables. Sets. SQL and PL/SQL. Logic sitting right next to the data where it belongs. I could look at a table and understand it. I could write a query and get a result. The database was my safe harbor in a storm of jargon I didn&#39;t understand.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That bias stuck with me for a long time.&amp;nbsp;&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;/h3&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;REST Didn’t Fix the Mindset&amp;nbsp;&lt;/h3&gt;&lt;div&gt;Fast forward a decade. SOAP was finally out of fashion (h/t to everyone who survived that era). REST and JSON were the
  new hotness. We were told this was &quot;better.&quot; And structurally, sure, it was.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A few years back, I poked around with a Strava app to see if I was just being a crank. Clean endpoints. JSON
  payloads. Reasonable docs.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And it was still exhausting.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Not because REST was inherently bad, but because the underlying mindset hadn&#39;t shifted an inch. I was still being
  handed &quot;object-shaped&quot; payloads and expected to navigate an object graph like a tourist without a map. Nested
  structures. Lists of things containing lists of other things. Manual parsing until my eyes bled.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That wasn’t a data problem. It was an OO worldview leaking all over my integration boundary. I wasn’t getting result
  sets; I was getting objects pretending to be data.&amp;nbsp;&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;/h3&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;PL/SQL Was Already the API (We Just Forgot)&amp;nbsp;&lt;/h3&gt;&lt;div&gt;Here’s the part that often gets missed: &lt;b&gt;PL/SQL has always been the API&lt;/b&gt;.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A PL/SQL procedure returning a ref cursor isn&#39;t some low-level implementation detail. It’s a contract. It’s the
  database saying, “Here is a defined shape of data. Consume it as a set.”&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That distinction matters.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A result set is declarative. It’s complete. It has no behavior, no lifecycle, no implied navigation path. It just is.
  Objects, on the other hand, carry all this baggage about how they want to be used. They imply traversal, ownership, and
  state transitions.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One is about truth. The other is about interaction. Most APIs were designed by app devs, so they expose objects. Not
  data.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It&#39;s probably why I loved APEX so much. It didn&#39;t ask me to pretend my data was a &quot;user object,&quot; it just asked me for the query.&lt;br /&gt;&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;/h3&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;AI Is the New Translation Layer&amp;nbsp;&lt;/h3&gt;&lt;div&gt;What finally broke the barrier for me wasn&#39;t some breakthrough in REST design. It was AI.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Today, I don&#39;t waste my life manually mapping JSON payloads into structures. I don’t read API docs line-by-line trying
  to guess where the edge cases are hiding. I just hand the spec to the machine.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My workflow is now dead simple:&lt;/div&gt;&lt;div&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Grab the API key.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Stash it in the system keychain.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Give the spec to the AI and let it do the grunt work.&amp;nbsp;&lt;/li&gt;&lt;/ol&gt;Pagination, retries, flattening, normalization; the machine handles all the deterministic boring stuff. What I want on
  the other side isn&#39;t an object model.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I want result sets.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Give me the rows and columns. Give me something I can join, constrain, and reason about at rest.&amp;nbsp;&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;/h3&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;From OO Friction to Set-Based Speed&amp;nbsp;&lt;/h3&gt;&lt;div&gt;Once that API output is normalized into a set, the friction evaporates.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I stop worrying about endpoint &quot;shapes&quot; and start thinking about data quality. I stop writing glue code and start
  defining truth. This is where PL/SQL shines. It doesn&#39;t want you to think in objects; it wants you to think in
  operations over sets. It wants logic close enough to the data that violating a business rule is actually difficult.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;APIs that dump object graphs on you fight that model. APIs that deliver result sets fit into it like a glove.&amp;nbsp;&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;/h3&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;APIs Are Just Addresses&amp;nbsp;&lt;/h3&gt;&lt;div&gt;If you look at it the right way, APIs aren&#39;t applications. They&#39;re just addresses.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A table is one physical address. A view is another. A remote API endpoint is just a slightly more annoying address. The
  &quot;brain&quot;—the business definition—doesn&#39;t live at the address. Neither does the &quot;brawn&quot; (the execution).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Those belong in a stable, declarative core. For me, that’s still the database.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;With AI translating API specs into tabular, set-friendly forms, external APIs finally behave like first-class data
  sources instead of OO intrusions.&amp;nbsp;&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;/h3&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The New Era of Data Integration&lt;/h3&gt;&lt;div&gt;&lt;div&gt;For a long time, integrating with external APIs felt like a chore because it forced us to abandon our set-based mindset. We were stuck parsing hierarchies instead of querying data.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That manual struggle is over.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;With AI acting as the translation layer, we can finally overcome that old &quot;impedance mismatch&quot; between objects and sets. We can normalize the world&#39;s objects into the sets we need to build real applications. The &quot;API barrier&quot; has turned into a bridge. We can stop worrying about the shape of the payload and get back to what we do best: defining the truth of the data.&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/2874916995633862369/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/2874916995633862369' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/2874916995633862369'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/2874916995633862369'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2026/05/if-you-were-database-guy-in-early-2000s.html' title='The Death of the API Barrier: From Jargon Intimidation to Result Sets and AI'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggrBhyphenhyphenq-YDxhmaZA-qsIy6eReSN6LSeOu-8LnT___LC3xpHarKNHj2dBPBpiardepnrKP_SHXb-FcsKGykr9j9V9cNF7HccJCzdK6AmG_Y6wVekKTpoCYmTsKWPjZTHW8-KjA2vsDqjJ9n11RaCZinpNwcyx-rY34uS4Er1kKdk5ZHLSukUGsom1b_I-4/s72-w400-h218-c/oraclenerd_api_and_ai.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-6701460467758717360</id><published>2026-04-23T22:10:00.001-04:00</published><updated>2026-04-23T22:10:40.720-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ai"/><category scheme="http://www.blogger.com/atom/ns#" term="kate"/><title type='text'>AI Didn’t Know the Law. It Made the Path Visible.</title><content type='html'>
&lt;h3&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiZA6dwlcbvAtE6fR1TMm8FoVrqZX44HjUOIderDitoOVPsN9P16UCHDQ9Q6MeMQTLo5N2slH5WyGFQZqNAQgISOC4tB8mrmrhuyPTEPJOtE7xLfAczSomHnvHl4CdB58CsyyGb2JGD7V43SbqzpqFFbh-dFopLVgRHrb-GE2W5vI_mdk9QaxIsy-qiF_Q&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;640&quot; data-original-width=&quot;640&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiZA6dwlcbvAtE6fR1TMm8FoVrqZX44HjUOIderDitoOVPsN9P16UCHDQ9Q6MeMQTLo5N2slH5WyGFQZqNAQgISOC4tB8mrmrhuyPTEPJOtE7xLfAczSomHnvHl4CdB58CsyyGb2JGD7V43SbqzpqFFbh-dFopLVgRHrb-GE2W5vI_mdk9QaxIsy-qiF_Q&quot; width=&quot;240&quot; /&gt;&lt;/a&gt;&lt;/div&gt;How I &lt;i&gt;finally&lt;/i&gt; appealed a denied insurance claim&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://www.oraclenerd.com/search/label/kate&quot;&gt;Kate&lt;/a&gt;&amp;nbsp;(now 21!) had dental surgery on 12/01/2025, a 4-5 hour procedure.&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;I don’t pay much attention to insurance stuff because it’s overwhelming. Before I joined my current company, it was also genuinely hard and expensive. Every day I’m grateful for my employer&#39;s coverage and, by extension, the generosity that makes it possible.&lt;/p&gt;

&lt;p&gt;Kate has had 3–4 major dental surgeries over the last couple of years. She doesn’t technically qualify as “hillbilly” yet. Her dentist says that’s eight or fewer teeth. 😆&lt;br /&gt;&lt;br /&gt;Kate also requires general anesthesia.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Dental surgery is not cheap, which means I know the exact limits of our dental coverage: $2,500 per year. Her most recent surgery came in just north of five figures. Thankfully, Kate has Medicaid as secondary insurance. Less thankfully, her dentist, who is excellent, no longer accepts Medicaid.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;About a month later, another bill arrived. This one was for anesthesia. It was roughly half the cost of the surgery itself. Sigh.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;I called the anesthesiologist’s office and learned they didn’t have Kate’s current insurance information. I gave it to them and asked them to resubmit the claim. They did. Denied. Denial code: 001.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;This is classified as dental work, so medical does not cover anesthesia. I think. 001 isn’t super descriptive, it says:&lt;/p&gt;

&lt;blockquote&gt;
    We denied this service. Your benefits don&#39;t cover this kind of care. You can check your plan documents or go to the Benefits section of our website for a searchable list of what&#39;s covered.
&lt;/blockquote&gt;

&lt;p&gt;Not super descriptive. AI (Gemini CLI) to the rescue. I downloaded the EOB and asked Gemini to scan it. It did and came back the above so I asked if it there were any other reasons possible?&lt;/p&gt;

&lt;blockquote&gt;
    While the document itself doesn&#39;t provide a specific medical rationale beyond the generic reason code 001 (&quot;Your benefits don&#39;t cover this kind of care&quot;), we can infer a highly likely explanation based on Kate&#39;s profile and typical insurance practices. Given that Kate&#39;s diagnosis is Developmentally Disabled, the most common scenario for an automatic denial like this is:
    &lt;br /&gt;&lt;br /&gt;
    &lt;b&gt;The Underlying Procedure was Dental:&lt;/b&gt; It is very common for special needs individuals to require general anesthesia for routine dental work that a neurotypical patient might do awake. Because routine dental care is generally excluded from medical plans, the automated claims system will automatically deny the associated anesthesia as &quot;not covered care,&quot; even though the anesthesia itself is medically necessary due to her disability.
&lt;/blockquote&gt;

&lt;p&gt;“Kate’s profile.” That’s a reference to other AI work I’ve been doing trying to make my life just a bit easier handling all the bureaucracy surrounding her (Guardianship, SSI, etc). My next prompt was, “How do I appeal?”&lt;/p&gt;

&lt;p&gt;This is where it gets super fun and unexpected. With that other context, “Kate’s Profile,” Gemini’s first response was:&lt;/p&gt;

&lt;blockquote&gt;
    I will research Florida&#39;s specific legal requirements for anesthesia coverage for individuals with developmental disabilities and provide the exact steps to file the appeal with the insurance provider.
&lt;/blockquote&gt;

&lt;p&gt;It came back with this:&lt;/p&gt;

&lt;blockquote&gt;
    ✦ To appeal this denial, you need to challenge the automated determination that the care is &quot;not covered.&quot; Because Kate has a developmental disability, Florida law likely requires them to cover the anesthesia and facility charges, even if the underlying procedure (like dental work) is not normally covered.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;
    &lt;b&gt;The Strategy: Use Florida Law&lt;/b&gt;
    &lt;br /&gt;
    Florida law mandates that health insurance policies must cover general anesthesia and associated hospital/facility charges for dental procedures if the patient meets specific criteria. Since Kate is over age 8, your appeal will rely on:
    &lt;br /&gt;&lt;br /&gt;
    &lt;b&gt;Statute: Fla. Stat. § 627.65755&lt;/b&gt;
    &lt;br /&gt;&lt;br /&gt;
    &lt;b&gt;The Argument:&lt;/b&gt; Kate has a developmental disability (as noted in her profile.json) that creates a &quot;significant or undue medical risk&quot; if dental or minor medical treatment were performed without general anesthesia in a controlled environment.
&lt;/blockquote&gt;

&lt;p&gt;This isn’t an example of AI “knowing the law.” It’s an example of AI making a path visible that was previously opaque enough to stop me from trying.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;This is the second time in as many weeks that it has helped me overcome a bureaucratic hurdle that usually stops me from pursuing a thing. The last time, it helped me transfer Kate’s Conservator Payee (SSI) from my mom to myself. My mom handled it previously because I would not engage with that labyrinthine system. She’s retired. It took her 10 months. I’m ridiculously grateful and lucky.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;If you’re looking for ways to utilize AI, here’s another.&amp;nbsp;&lt;/p&gt;&lt;p&gt;*Editor&#39;s Note&lt;/p&gt;&lt;p&gt;I posted this internally a few weeks back. I&#39;m slowing making my way back out into public waters.&amp;nbsp;&lt;/p&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/6701460467758717360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/6701460467758717360' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/6701460467758717360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/6701460467758717360'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2026/04/ai-didnt-know-law-it-made-path-visible.html' title='AI Didn’t Know the Law. It Made the Path Visible.'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/a/AVvXsEiZA6dwlcbvAtE6fR1TMm8FoVrqZX44HjUOIderDitoOVPsN9P16UCHDQ9Q6MeMQTLo5N2slH5WyGFQZqNAQgISOC4tB8mrmrhuyPTEPJOtE7xLfAczSomHnvHl4CdB58CsyyGb2JGD7V43SbqzpqFFbh-dFopLVgRHrb-GE2W5vI_mdk9QaxIsy-qiF_Q=s72-c" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-8435408915112293195</id><published>2026-04-18T21:37:00.002-04:00</published><updated>2026-04-18T21:37:47.510-04:00</updated><title type='text'>It&#39;s Been a Minute...</title><content type='html'>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkANnUmrVD8QH9JaKi78DxJHGHgEy6-DXyqFAWhn2nLL75GFopwmCfZPh4KM6-aW8vh1MDpThDkbgK4KWPzNrOGjVVYqdTzlbSC4zg0vJMYfpBr_MnV_fZp1Mpm2C0WpVMdrfoBAEPcMACGC75VZCVjXP-HTgAOAaJv6L4gtO6T40RT9MxE5b6V5S0wi4/s480/tom_hanks_waving.gif&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;270&quot; data-original-width=&quot;480&quot; height=&quot;208&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkANnUmrVD8QH9JaKi78DxJHGHgEy6-DXyqFAWhn2nLL75GFopwmCfZPh4KM6-aW8vh1MDpThDkbgK4KWPzNrOGjVVYqdTzlbSC4zg0vJMYfpBr_MnV_fZp1Mpm2C0WpVMdrfoBAEPcMACGC75VZCVjXP-HTgAOAaJv6L4gtO6T40RT9MxE5b6V5S0wi4/w370-h208/tom_hanks_waving.gif&quot; width=&quot;370&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Hi.&lt;p&gt;&lt;/p&gt;&lt;p&gt;It&#39;s been a while.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Not sure if this is a one-off or not, but I&#39;m going to give it another go. I miss writing (publicly).&lt;/p&gt;&lt;p&gt;Like, this is super awkward. &quot;What do I say?&quot;&lt;br /&gt;&lt;br /&gt;&quot;How are you?&quot;&lt;/p&gt;&lt;p&gt;&quot;Things are good.&quot;&lt;br /&gt;&lt;br /&gt;&quot;How are &lt;i&gt;you&lt;/i&gt;?&quot;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/8435408915112293195/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/8435408915112293195' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/8435408915112293195'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/8435408915112293195'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2026/04/its-been-minute.html' title='It&#39;s Been a Minute...'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkANnUmrVD8QH9JaKi78DxJHGHgEy6-DXyqFAWhn2nLL75GFopwmCfZPh4KM6-aW8vh1MDpThDkbgK4KWPzNrOGjVVYqdTzlbSC4zg0vJMYfpBr_MnV_fZp1Mpm2C0WpVMdrfoBAEPcMACGC75VZCVjXP-HTgAOAaJv6L4gtO6T40RT9MxE5b6V5S0wi4/s72-w370-h208-c/tom_hanks_waving.gif" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-5560614034204442186</id><published>2016-08-23T16:10:00.001-04:00</published><updated>2016-08-23T16:11:25.557-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="2016"/><category scheme="http://www.blogger.com/atom/ns#" term="book"/><category scheme="http://www.blogger.com/atom/ns#" term="plsql"/><category scheme="http://www.blogger.com/atom/ns#" term="sql"/><title type='text'>Real World SQL and PL/SQL: Advice from the Experts</title><content type='html'>&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;/div&gt;
&lt;a href=&quot;https://www.amazon.com/Real-World-SQL-PL-Experts/dp/1259640973&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh579EZW-pGNHjzX3GpdjGzL9Fl0Gzfm2SSK3BfIOPxSRmBZzmmtHFJNt271fj4abvlL0ggYihSVyWf8end_peZLGcUPMVglhGNydnZTFvA7frOOkfRLPeMcHu3T8k0UAPSyCrAMPcL69A/s200/Screenshot+from+2016-08-22+21%253A12%253A16.png&quot; width=&quot;162&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Because my hero is &lt;a href=&quot;https://twitter.com/carymillsap&quot;&gt;Cary Millsap&lt;/a&gt;, I&#39;m going to &lt;a href=&quot;http://carymillsap.blogspot.com/2008/07/christian-antogninis-new-book.html&quot;&gt;do what he did&lt;/a&gt; and publish my &lt;strike&gt;foreword&lt;/strike&gt; Preface. All joking aside, I consider myself incredibly fortunate to have been included in this project. I learned...a lot, by simply trying to find the author&#39;s mistakes (and there were not many). There was a lot more work than I expected, as well. (Technical) Editing is lot easier than writing, to be sure.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Brendan Tierney and Heli Helskyaho approached me in March 2015 about being an author on this book, along with Arup Nanda and Alex Nuijten. Soon after, we picked up Martin Widlake. To say that I was honored to be asked would be a gross understatement. Rather quickly though, I realized that I did not have the mental energy to devote to the project and didn’t want to put the other authors at risk. Still wanting to be part of the book, I suggested that I be the Technical Editor and they graciously accepted my new role.&lt;br /&gt;
&lt;br /&gt;
This is my first official role as Technical Editor, but I’ve been doing it for years through work; checking my work, checking others work, etc. Having a touch of Obsessive Compulsive Disorder (OCD) helps greatly.&lt;br /&gt;
&lt;br /&gt;
All testing was done with the pre-built &lt;a href=&quot;http://www.oracle.com/technetwork/community/developer-vms-192663.html&quot;&gt;Database App Development VM&lt;/a&gt; provided by OTN/Oracle which made things easy. Configuration for testing was simple with the instructions provided in those chapters that required it.&lt;br /&gt;
&lt;br /&gt;
One of my biggest challenges was the multi-tenant architecture of Oracle 12c. I haven’t done DBA type work in a few years, so trying to figure out if I should be doing something in the root container (CDB) or the pluggable database (PDB) was fun. Other than that though, the instructions provided by the authors were pretty easy to follow.&lt;br /&gt;
&lt;br /&gt;
Design (data modeling, Edition Based Redefinition, VPD), Security (Redaction/Masking, Encryption/Hashing), Coding (Reg Ex, PL/SQL, SQL), Instrumentation, and “Reporting” or turning that raw data into actionable information (Data Mining, Oracle R, Predictive Queries). These topics are covered in detail throughout this book. Everything a developer would need to build an application from scratch.&lt;br /&gt;
&lt;br /&gt;
Probably my favorite part of this endeavor is that I was forced to do more than simply see if it works. Typically when reading a book, or blog entry, I’ll grab the technical solution and move on often skipping the Why, When, and Where. How, to me, is relatively easy. I read AskTom daily for many years, it was my way of taking a break without getting in trouble. At first, it was to see how particular solutions were solved, occasionally using it for my own problems. After a year or two, I wanted to understand the Why of doing it a certain way and would look for those responses where Tom provided insight into his approach.&lt;br /&gt;
&lt;br /&gt;
That’s what I got reviewing this book. I was allowed into their minds, to not only see How they solved technical problems, but Why. This is invaluable for developer’s and DBAs. Most of us can figure out How to solve specific technical issues, but to reach that next level we need to understand the Why, When and Where. This book provides that.&lt;br /&gt;
&lt;br /&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/5560614034204442186/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/5560614034204442186' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/5560614034204442186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/5560614034204442186'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2016/08/real-world-sql-and-plsql-advice-from.html' title='Real World SQL and PL/SQL: Advice from the Experts'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh579EZW-pGNHjzX3GpdjGzL9Fl0Gzfm2SSK3BfIOPxSRmBZzmmtHFJNt271fj4abvlL0ggYihSVyWf8end_peZLGcUPMVglhGNydnZTFvA7frOOkfRLPeMcHu3T8k0UAPSyCrAMPcL69A/s72-c/Screenshot+from+2016-08-22+21%253A12%253A16.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-7637224728828627813</id><published>2015-07-09T15:04:00.001-04:00</published><updated>2015-07-09T15:04:53.745-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="2015"/><category scheme="http://www.blogger.com/atom/ns#" term="kate"/><category scheme="http://www.blogger.com/atom/ns#" term="kscope"/><title type='text'>Kscope15 - It&#39;s a Wrap, Part II</title><content type='html'>Another fantastic Kscope in the can. 

&lt;br /&gt;&lt;br /&gt;

This was my final year in an official capacity which was a lot more difficult to deal with than I had anticipated. Here&#39;s my record of service:

&lt;br /&gt;

&lt;ul&gt;
  &lt;li&gt;2010 (2011, Long Beach) - I was on the database abstract review committee run by Lewis Cunningham. I ended up volunteering to help put together the Sunday Symposium and with the help of &lt;a href=&quot;https://twitter.com/ddelmoli&quot;&gt;Dominic Delmolino&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/carymillsap&quot;&gt;Cary Millsap&lt;/a&gt; and &lt;a href=&quot;https://twitter.com/krisrice&quot;&gt;Kris Rice&lt;/a&gt;, I felt I did a pretty decent job.&lt;/li&gt;
  &lt;li&gt;2011 (2012, San Antonio) - Database track lead. I believe this is the year that Oracle started running the Sunday Symposiums. Kris again led the charge with some input from those other two from the year before, i.e. DevOps oriented&lt;/li&gt;
  &lt;li&gt;2012 (2013, New Orleans) Content co-chair for the traditional stuff (Database, APEX, ADF), Interview Monkey (&lt;a href=&quot;https://www.youtube.com/watch?v=c7C2t-lp37M&quot;&gt;Tom Kyte OMFG!&lt;/a&gt;), OOW/ODTUG Coordinator, etc.&lt;/li&gt;
  &lt;li&gt;2013 (2014, Seattle) Content co-chair for the traditional stuff (Database, APEX, ADF), Interview Monkey, OOW/ODTUG Coordinator, etc.&lt;/li&gt;
  &lt;li&gt;2014 (2015, Hollywood, FL) Content co-chair for the traditional stuff (Database, APEX, ADF)&lt;/li&gt;
&lt;/ul&gt;

&lt;br /&gt;

This has been a wonderful time for me both professionally and, more importantly to me, personally. Obviously I had a big voice in the direction of content. Also and maybe hard to believe, I actually presented for the first time. Slotted against Mr. Kyte. I reminded everyone of that too. Multiple times. It seemed to go well though. Only a &lt;a href=&quot;https://twitter.com/Troy_Ligon/status/612973988990590976&quot;&gt;few&lt;/a&gt; made fun of me.

&lt;br /&gt;&lt;br /&gt;

I was constantly recruiting too. &quot;Did you submit an abstract?&quot; &quot;No, why not?&quot; and I&#39;d go into my own personal diatribe (ignoring my own lack of presenting) into why they should present. &lt;a href=&quot;https://twitter.com/epm_queen&quot;&gt;Sarah Craynon Zumbrum&lt;/a&gt; summed it up pretty well in a recent &lt;a href=&quot;http://epmqueen.com/2015/07/01/on-abstracts/&quot;&gt;article&lt;/a&gt;. 

&lt;br /&gt;&lt;br /&gt;

But it was the connections I made, the people I met, the stories I shared (#ampm, #cupcakeshirt, etc), and the friends that I made, that&#39;s what has had the most impact on me. Kscope is unique in that way because of it&#39;s size...at Collaborate or OOW, you&#39;ll be lucky to see someone more than once or twice, at Kscope you&#39;re running into everyone constantly. 

&lt;br /&gt;&lt;br /&gt;
How could I forget? #tadasforkate! This year was even more special. For those that don&#39;t know, &lt;a href=&quot;http://www.oraclenerd.com/search/label/kate&quot;&gt;Katezilla&lt;/a&gt; is my profoundly delayed but equally profoundly happy 10 y/o daughter. Just prior to the conference her physical therapist taught her &quot;tada!&quot; and Kate would hold her hands up high in the air and everyone around would yell, Tada! I got this crazy idea to ask others to do it and I would film it. Thirty or forty videos and hundreds of participants later...

&lt;br/&gt;&lt;br /&gt;

&lt;iframe width=&quot;640&quot; height=&quot;480&quot; src=&quot;https://www.youtube.com/embed/ilrctDbFE_4&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;
 
&lt;br /&gt;&lt;br /&gt;

So a gigantic thank you to everyone who made this possible for me. 

&lt;br /&gt;

Here&#39;s a short list of those that had a direct impact on me...
&lt;ul&gt;
  &lt;li&gt;Lewis Cunningham - he asked me to be a reviewer which started all of this off.&lt;/li&gt;
  &lt;li&gt;Mike Riley - can&#39;t really say enough about Mike. After turning me away a long time ago (jerk), he was probably my biggest supporter over the years. (Remind me next year to you tell you about &quot;The Hug.&quot;). Mike, and his family, are very dear to me.&lt;/li&gt;
  &lt;li&gt;Monty Latiolais (rhymes with Frito Lay I would tell myself) - How can you not love this guy?&lt;/li&gt;
  &lt;li&gt;Natalie Delemar - Co-chair for EPM/BI and then boss as Conference Chair.&lt;/li&gt;
  &lt;li&gt;Opal Alapat - Co-chair for EPM/BI and one of my favorite humans ever invented. I aspire to be more organized, assertive, and bad-ass like Opal.&lt;/li&gt;
&lt;/ul&gt;

That list is by no means exhaustive. It doesn&#39;t even include staff at YCC, like Crystal Walton, Lauren Prezby and everyone else there. Nor does it include the very long list of Very Special People I&#39;ve met. I consider myself very fortunate and incredibly grateful.

&lt;br /&gt;&lt;br /&gt;

&lt;b&gt;What&#39;s the future hold?&lt;/b&gt;&lt;br /&gt; I have no idea. My people are in talks with &lt;a href=&quot;https://twitter.com/helenjsanders&quot;&gt;Helen J. Sander&#39;s&lt;/a&gt; people to do one or more presentations next year, so there&#39;s that. Speaking of which...it&#39;s in Chicago. Abstract submissions start soon, I hope you plan on submitting. If you&#39;re not ready to submit, I hope you take try to take part in shaping the content by finding one of about 10 abstract review committees. Who knows where they may lead you? 

&lt;br /&gt;&lt;br /&gt;

Finally, here&#39;s the &lt;i&gt;It&#39;s a Wrap&lt;/i&gt; video from Kscope15 (see Helen&#39;s story there). Here&#39;s &lt;a href=&quot;http://kscope16.com/&quot;&gt;Kscope16&#39;s site&lt;/a&gt;. Go sign up.

&lt;br /&gt;&lt;br /&gt;

&lt;iframe width=&quot;640&quot; height=&quot;360&quot; src=&quot;https://www.youtube.com/embed/7ev7xwpoKkw&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;



&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/7637224728828627813/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/7637224728828627813' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/7637224728828627813'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/7637224728828627813'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2015/07/kscope15-its-wrap-part-ii.html' title='Kscope15 - It&#39;s a Wrap, Part II'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img.youtube.com/vi/ilrctDbFE_4/default.jpg" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-7922295549889034626</id><published>2015-04-22T22:57:00.000-04:00</published><updated>2015-04-22T22:58:59.012-04:00</updated><title type='text'>Is MERGE a bug? </title><content type='html'>A few years back I pondered whether &lt;a href=&quot;www.oraclenerd.com/2009/01/is-distinct-bug.html&quot;&gt;DISTINCT was a bug&lt;/a&gt;.

&lt;br/&gt;&lt;br/&gt;

My premise was that if you are depending on DISTINCT to return a correct result set, something is seriously wrong with your table design. I was reminded of this again recently when I ran across Kent Graziano&#39;s post on &lt;a href=&quot;http://kentgraziano.com/2013/08/25/better-data-modeling-are-you-making-these-3-beginner-mistakes-in-your-data-models&quot;&gt;Better Data Modeling: Are you making these 3 beginner mistakes in your data models?&lt;/a&gt;. Specifically:

&lt;br/&gt;

&lt;blockquote&gt;
Instead of that, you should be defining a natural, or business, key for every table in your system. A natural key is a an attribute or set of attributes (that occur naturally in the data set) required to uniquely identify a row in that table. In addition you should define a Unique Key Constraint on those attributes in the database. Then you can be sure you will not get any duplicate data into the tables.

&lt;br/&gt;&lt;br/&gt;

CLARIFICATION: This point has caused a lot of questions and comments. To be clear, the mistake here is to have ONLY defined a surrogate key. i believe that even if using surrogate keys is the best solution for your design, you should ALSO define an alternate unique natural key.&lt;/blockquote&gt;

So why MERGE?
&lt;br/&gt;&lt;br/&gt;

I learned about the MERGE statement in 2008. During an interview, &lt;a href=&quot;http://obieeone.com/&quot;&gt;Frank Davis&lt;/a&gt; asked me about when I would use it. I didn&#39;t even know what it was (and admitted that) but I went home that night and...wait...I think he asked me about &lt;a href=&quot;http://www.oraclenerd.com/2008/05/multi-table-inserts.html&quot;&gt;multi table inserts&lt;/a&gt;. Whatever, credit is still going to Mr. Davis. Where was I? OK, so I had been working with Oracle for about 6 years at that point and I didn&#39;t know about it. My initial reaction was to use it everywhere (not really)! You know, shiny object and all. Look! Squirrel!

&lt;br/&gt;&lt;br/&gt;

Why am I considering MERGE a bug? Let me be more specific. I was working with a couple of tables and had not written the API for them yet and a developer was writing some PL/SQL to update the records from APEX. In his loop he had a MERGE. I realized at that moment there was 1, no surrogate key and 2, no natural key defined (which ties in with Kent&#39;s comments up above). Upon realizing the developer was doing this, I knew immediately what the problem was (besides not using a PL/SQL API to nicely encapsulate the business logic). The table was poorly designed. 

&lt;br/&gt;&lt;br/&gt;

Easy fix. Update the table with a surrogate key and define a natural key. I was thankful for the reminder, I hadn&#39;t added the unique constraint yet. Of course had I written the API already I probably would have noticed the design error, either way, a win for design. 

&lt;br/&gt;&lt;br/&gt;

Now, there are perfectly good occasions to use the MERGE statement. Most of those, &lt;a href=&quot;http://www.oraclenerd.com/2013/04/caveats.html&quot;&gt;to me anyway&lt;/a&gt;, relate to legacy systems where you don&#39;t have the ability to change the underlying table structures (or it&#39;s just cost prohibitive) or ETL, where you want to load/update a dimension table in your data warehouse. 

&lt;br/&gt;&lt;br/&gt;

Noons, how&#39;s that? First time out in 10 months. Thanks for the push.
&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/7922295549889034626/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/7922295549889034626' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/7922295549889034626'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/7922295549889034626'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2015/04/is-merge-bug.html' title='Is MERGE a bug? '/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-4091188032342874600</id><published>2014-06-04T18:13:00.000-04:00</published><updated>2014-06-04T18:13:26.302-04:00</updated><title type='text'>Fun with SQL - Silver Pockets Full</title><content type='html'>&lt;a href=&quot;http://www.snopes.com/inboxer/trivia/fivedays.asp&quot;&gt;Silver Pockets Full&lt;/a&gt;, send this message to your friends and in four days the money will surprise you. If you don&#39;t, well, a pox on your house. Or something like that. I didn&#39;t know what it was, I just saw this in my FB feed:

&lt;br /&gt;&lt;br /&gt;

&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgh7xQ76kPdE4HBSD5H08ba2PxdmzA4bF0QekhJSgV3MKoxEag2BvgzWEtJ_SjX_qgH-HWLbDPBNcqv22vufOWGxYnHusxK7t8jOlKKLnM2kM7vmqG5cJDsAaLfgGMP-BM0tXLiCwk1j0A/s800/10256953_1482404708655173_9115989789244265213_n.jpg&quot; style=&quot;padding-left: 25px;&quot; /&gt;

&lt;br /&gt;&lt;br /&gt;

Back in &lt;a href=&quot;http://www.oraclenerd.com/2013/11/fun-with-sql-my-birthday.html&quot;&gt;November&lt;/a&gt;, I checked to see the frequency of having incremental numbers in the date, like 11/12/13 (my birthday) and 12/13/14 (kate&#39;s birthday). I don&#39;t want to hear how the rest of the world does their dates either, I know (I now write my dates like YYYY/MM/DD on everything, just so you know, that way I can sort it...or something). 

&lt;br /&gt;&lt;br /&gt;

Anyway, SQL to test out the claim of once every 823 years. Yay SQL. 

&lt;br /&gt;&lt;br /&gt;

OK, I&#39;m not going to go into the steps necessary because I&#39;m lazy (and I&#39;m just lucky to be writing here), so here it is:&lt;pre class=&quot;code&quot;&gt;select *
from
  (
    select 
      to_char( d, &#39;yyyymm&#39; ) year_month,
      count( case
               when to_char( d, &#39;fmDay&#39; ) = &#39;Saturday&#39; then 1
               else null
             end ) sats,
      count( case
               when to_char( d, &#39;fmDay&#39; ) = &#39;Sunday&#39; then 1
               else null
             end ) suns,
      count( case
               when to_char( d, &#39;fmDay&#39; ) = &#39;Friday&#39; then 1
               else null
             end ) fris
    from
      (
        select to_date( 20131231, &#39;yyyymmdd&#39; ) + rownum d
        from dual
          connect by level &lt;= 50000
      )
    group by 
      to_char( d, &#39;yyyymm&#39; )
  )
where fris = 5
  and sats = 5
  and suns = 5&lt;/pre&gt;So over the next 50,000 days, this happens 138 times. I&#39;m fairly certain that doesn&#39;t rise to the once every 823 years claim. But it&#39;s cool, maybe.&lt;pre class=&quot;code&quot;&gt;YEAR_MONTH       SATS       SUNS       FRIS
---------- ---------- ---------- ----------
201408              5          5          5 
201505              5          5          5 
201601              5          5          5 
201607              5          5          5 
201712              5          5          5 
128 more occurrences...
214607              5          5          5 
214712              5          5          5 
214803              5          5          5 
214908              5          5          5 
215005              5          5          5 

 138 rows selected &lt;/pre&gt;I&#39;m not the only dork that does this either, here&#39;s one in &lt;a href=&quot;http://perlbuzz.com/2013/03/debunking-the-five-weekends-every-823-years-myth-with-perl.html&quot;&gt;perl&lt;/a&gt;. I&#39;m sure there are others, but again, I&#39;m lazy.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/4091188032342874600/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/4091188032342874600' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/4091188032342874600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/4091188032342874600'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2014/06/fun-with-sql-silver-pockets-full.html' title='Fun with SQL - Silver Pockets Full'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgh7xQ76kPdE4HBSD5H08ba2PxdmzA4bF0QekhJSgV3MKoxEag2BvgzWEtJ_SjX_qgH-HWLbDPBNcqv22vufOWGxYnHusxK7t8jOlKKLnM2kM7vmqG5cJDsAaLfgGMP-BM0tXLiCwk1j0A/s72-c/10256953_1482404708655173_9115989789244265213_n.jpg" height="72" width="72"/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-7791089215719894671</id><published>2014-04-10T22:44:00.002-04:00</published><updated>2014-04-10T22:44:31.650-04:00</updated><title type='text'>The Riley Family, Part III</title><content type='html'>&lt;img style=&quot;align: center;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSdvuKL8U7FCPJ_7h6cJ9VTpKKol9LytaqYbn9de10z8NGObj_dJBuzZAXuj25CdDX6pl0ciCF3ru2QzdC2Kksz7LuVQVQzOrLC6yLqyNyJLMDtfxAQvaGgvolQ6PWbZ2a9UdMw3Q39kk/s800/1509531_566260413449373_759515834_o.jpg&quot; /&gt;

&lt;br /&gt;
&lt;br /&gt;
That&#39;s Mike and Lisa, hanging out at the hospital. Mike&#39;s in his awesome cookie monster pajamas and robe...must be nice, right? Oh wait, it&#39;s not. You probably remember why he&#39;s there, Stage 3 cancer. The joys.
&lt;br /&gt;
&lt;br /&gt;

In October, we helped to send the entire family to &lt;a href=&quot;http://www.oraclenerd.com/2013/11/the-riley-family-part-ii.html&quot;&gt;Game 5 of the World Series&lt;/a&gt; (Cards lost, thanks Red Sox for ruining their night).
&lt;br /&gt;
&lt;br /&gt;

In November I started a GoFundMe &lt;a href=&quot;http://www.gofundme.com/fmcuta&quot;&gt;campaign&lt;/a&gt;, to date, with your help, we&#39;ve raised $10,999. We&#39;ve paid over 9 thousand dollars to the Riley family (another check to be cut shortly).  
&lt;br /&gt;
&lt;br /&gt;

In December, Mike had surgery. Details can be found &lt;a href=&quot;http://www.odtug.com/p/bl/et/blogid=1&amp;blogaid=315&quot;&gt;here&lt;/a&gt;. Shorter: things went fairly well, then they didn&#39;t. Mike spent 22 days in the hospital and lost 40 lbs. He missed Christmas and New Years at home with his family. But, as I&#39;ve learned over the last 6 months, the Riley family really knows how to take things in stride.
&lt;br /&gt;
&lt;br /&gt;
About 6 weeks ago Mike started round 2 of chemo, he&#39;s halfway through that one now. He complains (daily, ugh) about numbness, dizziness, feeling cold (he lives in St. Louis, are you sure it&#39;s not the weather?), and priapism (that&#39;s a lie...I hope). 
&lt;br /&gt;
&lt;br /&gt;
Mike being Mike though, barely a complaint (I&#39;ll let you figure out where I&#39;m telling a lie).
&lt;br /&gt;
&lt;br /&gt;
Four weeks ago, a chilly (65) Saturday night, Mike and Lisa call. &quot;Hey, I&#39;ve got some news for you.&quot;
&lt;br /&gt;
&lt;br /&gt;
&quot;Sweet,&quot; I think to myself. Gotta be good news.
&lt;br /&gt;
&lt;br /&gt;
&quot;Lisa was just diagnosed with breast cancer.&quot;
&lt;br /&gt;
&lt;br /&gt;
WTF?
&lt;br /&gt;
&lt;br /&gt;
ARE YOU KIDDING ME? (Given Mike&#39;s gallows humor, it&#39;s possible).
&lt;br /&gt;
&lt;br /&gt;
&quot;Nope. Stage 1. Surgery on April 2nd.&quot;
&lt;br /&gt;
&lt;br /&gt;
FFS
&lt;br /&gt;
&lt;br /&gt;
(Surgery was last week. It went well. No news on that front yet.)
&lt;br /&gt;
&lt;br /&gt;
Talking to them two of them that evening you would have no idea they BOTH have cancer. Actually, one of my favorite stories of the year...the hashtag for Riley Family campaign was #fmcuta. Fuck Mike&#39;s Cancer (up the ass). I thought that was hilarious, but I didn&#39;t think the Riley&#39;s would appreciate it. They did. They loved it. I still remember Lisa&#39;s laugh when I first suggested it. They&#39;ve dropped the latest bad news and Lisa is like, &quot;Oh, wait until you hear this. I have a hashtag for you.&quot;
&lt;br /&gt;
&lt;br /&gt;
&quot;What is it?&quot; (I&#39;m thinking something very...conservative. Not sure why, I should know better by now).
&lt;br /&gt;
&lt;br /&gt;
#tna
&lt;br /&gt;
&lt;br /&gt;
I think about that for about .06 seconds. Holy shit! Did you just say tna? Like &quot;tits and ass?&quot;
&lt;br /&gt;
&lt;br /&gt;
(sounds of Lisa howling in the background).
&lt;br /&gt;
&lt;br /&gt;
Awesome. See what I mean? Handling it in stride. 
&lt;br /&gt;
&lt;br /&gt;
&quot;We&#39;re going to need a bigger boat.&quot; All I can think about now is, &quot;what can we do now?&quot;
&lt;br /&gt;
&lt;br /&gt;
First, I raised the campaign goal to 50k. This might be ambitious, that&#39;s OK, cancer treatments are expensive enough for one person, and 10K (the original amount) was on the low side. So...50K. 

&lt;br /&gt;
&lt;br /&gt;

Second, &lt;a href=&quot;http://spendolini.blogspot.com/&quot;&gt;Scott Spendolini&lt;/a&gt; created a very cool APEX app, ostensibly called the Riley Support Group (website? gah). It&#39;s a calendar/scheduling app that allows friends and family coordinate things like meals, young human (children) care and other things that most of us probably take for granted. Pretty cool stuff. For instance, &lt;a href=&quot;http://evdbt.com/&quot;&gt;Tim Gorman&lt;/a&gt; provides pizza on Monday nights (Dinner from pizza hut...1 - large hand-tossed cheese lovers, 1 - large thin-crispy pepperoni, 1 - 4xpepperoni rolls, 1 - cheesesticks). 
&lt;br /&gt;
&lt;br /&gt;
Third. There is no third.

&lt;br /&gt;
&lt;br /&gt;
So many of you have donated your hard earned cash to the Riley family, they are incredibly humbled by, and grateful for, everyone&#39;s generosity. They aren&#39;t out of the woods yet. Donate more. Please. If you can&#39;t donate, see if there&#39;s something you can help out with (hit me up for details, Tim lives in CO, he&#39;s not really close). If you can&#39;t do either of those things, send them your prayers or your good thoughts. Any and all help will be greatly appreciated.
&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/7791089215719894671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/7791089215719894671' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/7791089215719894671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/7791089215719894671'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2014/04/the-riley-family-part-iii.html' title='The Riley Family, Part III'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSdvuKL8U7FCPJ_7h6cJ9VTpKKol9LytaqYbn9de10z8NGObj_dJBuzZAXuj25CdDX6pl0ciCF3ru2QzdC2Kksz7LuVQVQzOrLC6yLqyNyJLMDtfxAQvaGgvolQ6PWbZ2a9UdMw3Q39kk/s72-c/1509531_566260413449373_759515834_o.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-473884934359680075</id><published>2013-11-12T23:13:00.001-05:00</published><updated>2013-11-12T23:54:59.401-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="2013"/><category scheme="http://www.blogger.com/atom/ns#" term="family"/><category scheme="http://www.blogger.com/atom/ns#" term="kscope"/><category scheme="http://www.blogger.com/atom/ns#" term="odtug"/><title type='text'>The Riley Family, Part II</title><content type='html'>You didn&#39;t miss &lt;a href=&quot;http://www.odtug.com/p/bl/et/blogid=1&amp;blogaid=290&quot;&gt;Part I&lt;/a&gt;, at least not here you didn&#39;t.

&lt;br /&gt;&lt;br /&gt;

Many of you know Mike Riley. If you don&#39;t, here&#39;s a little history. He&#39;s the past president of ODTUG (for like 37 years or something) and for the last two years, he&#39;s served as Conference Chair for Kscope. Yeah, that doesn&#39;t really follow, but you know I&#39;m a bit...scattered. 

&lt;br /&gt;&lt;br /&gt;

Did you read the link above? OK, well, here&#39;s the skinny. Mike has rectal cancer. Stage III. If it weren&#39;t for the stupid cancer part, the jokes would abound. Oh wait, they do anyway. Mike was diagnosed shortly after #kscope13, right around his 50th birthday (Happy Birthday Mike, Love, Cancer!). Ugh. (I want to say, &quot;are you shittin&#39; me?&quot; see what I mean about the jokes? I can&#39;t help myself, I&#39;m 14). Needless to say, cancer isn&#39;t really a joke. We all know someone affected by it. It is...well, it&#39;s not fun. 

&lt;br /&gt;&lt;br /&gt;

Go read his post if you haven&#39;t already. I&#39;m going to give my version of that story. I&#39;ll wait...

&lt;br /&gt;&lt;br /&gt;

So, Sunday morning, Game 3 of the World Series went to the Cardinals in a very bizarre way. I was watching highlights that morning as I had missed the end of the game (doesn&#39;t everyone know that I&#39;m old and can&#39;t stay up that late to watch baseball?). Highlights. Mike lives in St. Louis. He&#39;s a Cardinal&#39;s fan. Wouldn&#39;t it be cool if he and his family could go to the game (mostly just his family, I don&#39;t like Mike that much). So I make some phone calls to see what people think of my idea. My idea is met with resistance. OK, I&#39;ll skip the people. Let&#39;s call Lisa (Mike&#39;s wife).

&lt;br /&gt;&lt;br /&gt;

Apparently Sunday&#39;s are technology free days in the Riley household, no response. I go for a bike ride, but I take my phone, just in case Lisa calls me back. After the halfway point, my phone rings, I jump off the bike to answer. 

&lt;br /&gt;&lt;br /&gt;

So I talked to Lisa about my idea, can Mike handle the chaos of a World Series game?

&lt;br /&gt;&lt;br /&gt;

We hang up and she goes to work. BTW, I asked her to keep my name out of it, but she didn&#39;t. We&#39;ll have words about that in the future. 

&lt;br /&gt;&lt;br /&gt;

She calls back (I think, it may have been over text, 2 weeks is an eternity to me). &quot;He doesn&#39;t think he can do it.&quot; 

&lt;br /&gt;&lt;br /&gt;

So I call Mike directly (Lisa had already spoiled the surprise.)

&lt;br /&gt;&lt;br /&gt;

&quot;What about Box seats? You know, where the people with top hats and monocles sit? Away from the rift-raft, much more comfortable and free food and beer.&quot;

&lt;br /&gt;&lt;br /&gt;

Backstory. Mike had finished his first round of chemo less than a week before Sunday. To make things worse, he decided it was a good time to throw out his back. He wasn&#39;t in the best of shape.

&lt;br /&gt;&lt;br /&gt;

Mike said he thought he could do it.

&lt;br /&gt;&lt;br /&gt;

OK, nay-sayers aside, let&#39;s see what we can do. I emailed approximately 50 people, mostly ODTUG people; board members, content leads, anyone I had in my address book. &quot;Hey, wouldn&#39;t it be great to send Mike and his family to Game 5 of the World Series? We need to do this quick, tickets will probably double in price tonight especially if the Cardinals win.&quot; (that would mean Game 5 would be a clincher for the Cardinals, at home, muy expensive). 

&lt;br /&gt;&lt;br /&gt;

Within about 20 minutes, a couple of people pledged $600. 

&lt;br /&gt;&lt;br /&gt;

Holy shit!

&lt;br /&gt;&lt;br /&gt;

At the prices I had seen, I was hoping to get between $50 and $100 from 50 people, &lt;i&gt;hoping&lt;/i&gt;. I had $600 already. Game starts. Now it&#39;s up to $1100 in pledges. Holy shit, Part II. This might just be possible. Another 30 minutes and were about an hour into Game 4. Ticket prices have already gone up by $250 a ticket. Given that maybe 4 people have responded and I have $1600 in pledges, I pull the trigger. I bought 4 box seat tickets for the Riley family. (I had to have a couple of beers because I was about to drop a significant chunk of change without actual cash in hand, I could be out a lot of money, liquid courage is awesome). 

&lt;br /&gt;&lt;br /&gt;

Tickets sent to the Riley family. Pretty good feeling.

&lt;br /&gt;&lt;br /&gt;

Like I said, I was confident, but I was scared. Before the end of the night though, there was over $5K pledged to get Mike and family to Game 5. Holy shit, Part III. 

&lt;br /&gt;&lt;br /&gt;

By midday Monday, pledges were well over $7K. I&#39;ll refer you back to Mike&#39;s &lt;a href=&quot;http://www.odtug.com/p/bl/et/blogid=1&amp;blogaid=290&quot;&gt;post&lt;/a&gt; for more details. Shorter: jerseys for the family and a limo to the game. 

&lt;br /&gt;&lt;br /&gt;

Here&#39;s the breakdown: 35 people pledged, and paid, $8,080. Holy shit, Part IV. Average donation was $230.86. Median was $200. Low was $30 and high was $1000. Six people gave $500 or more. Nineteen people gave $200 or more. The list is a veritable Who&#39;s Who in the Oracle community. 

&lt;br /&gt;&lt;br /&gt;

Tickets + Jerseys + Limo = $6027.76

&lt;br /&gt;&lt;br /&gt;

Riley family memory = Priceless.

&lt;br /&gt;&lt;br /&gt;

So, what happened to the rest? Well, they have bills. Lots of bills. With the remainder, $2052.24, we paid off some hospital bills of $1220.63. There is currently $831.61 that will be sent shortly. It doesn&#39;t stop there though. Cancer treatment is effing expensive. Mike has surgery in December. He&#39;ll be on bed rest for some time. His bed is 17 years old. He needs a new one. After that, more chemo and more bills. 

&lt;br /&gt;&lt;br /&gt;

&quot;Hey Chet, I&#39;d love to help the Riley family out, can I give you my money for them?&quot;

&lt;br /&gt;&lt;br /&gt;

Yes, absolutely. Help me help them. I started a &lt;a href=&quot;http://www.gofundme.com/fmcuta&quot;&gt;GoFundMe&lt;/a&gt; campaign. Goal is $10K. Any and all donations are welcome. Gifts include a thank you card from the Riley family and the knowledge that you helped out a fellow Oracle (nerd, definitely a nerd) in need. You can find the campaign &lt;a href=&quot;http://www.gofundme.com/fmcuta&quot;&gt;here&lt;/a&gt;. 
&lt;br /&gt;&lt;br /&gt;

If you can&#39;t donate money, I&#39;ve also created a hashtag so that we can show support for Mike and his family. It&#39;s #fmcuta (I&#39;ll let you figure out what it means). Words of encouragement are welcome and appreciated. 

&lt;br /&gt;&lt;br /&gt;

Thank you to the 35 who have already so generously given. Thank you to the rest of you who will donate or send out (rude) tweets. 


&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/473884934359680075/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/473884934359680075' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/473884934359680075'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/473884934359680075'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2013/11/the-riley-family-part-ii.html' title='The Riley Family, Part II'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-142980537232715092</id><published>2013-11-06T11:26:00.000-05:00</published><updated>2013-11-06T11:26:04.638-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="funny"/><category scheme="http://www.blogger.com/atom/ns#" term="random"/><category scheme="http://www.blogger.com/atom/ns#" term="sql"/><title type='text'>Fun with SQL - My Birthday</title><content type='html'>This year is kind of fun, my birthday is on November 12th (next Tuesday, if you want to send gifts). That means it will fall on 11/12/13. Even better perhaps, &lt;a href=&quot;http://www.oraclenerd.com/search/label/kate&quot;&gt;katezilla&#39;s&lt;/a&gt; birthday is December 13th. 12/13/14. What does this have to do with SQL?

&lt;br /&gt;&lt;br /&gt;

Someone mentioned to me last night that this wouldn&#39;t happen again for 990 years. I was thinking, &quot;wow, I&#39;m super special now (along with the other 1/365 * 6 billion people)!&quot; Or am I? I had to do the math. Since date math is hard, and math is hard, and I&#39;m good at neither, SQL to the rescue.

&lt;br /&gt;&lt;br /&gt;

&lt;pre class=&quot;code&quot;&gt;select 
  to_number( to_char( sysdate + ( rownum - 1 ), &#39;mm&#39; ) ) month_of,
  to_number( to_char( sysdate + ( rownum - 1 ), &#39;dd&#39; ) ) day_of,
  to_number( to_char( sysdate + ( rownum - 1 ), &#39;yy&#39; ) ) year_of,
  sysdate + ( rownum - 1 ) actual
from dual
  connect by level &lt;= 100000&lt;/pre&gt;

(In case you were wondering, 100,000 days is just shy of 274 years. 273.972602739726027397260273972602739726 to be more precise.)
&lt;br /&gt;&lt;br /&gt;

That query gives me this:

&lt;pre class=&quot;code&quot;&gt;MONTH_OF DAY_OF YEAR_OF ACTUAL   
-------- ------ ------- ----------
11       06     13      2013/11/06 
11       07     13      2013/11/07 
11       08     13      2013/11/08 
11       09     13      2013/11/09 
11       10     13      2013/11/10 
11       11     13      2013/11/11 
...&lt;/pre&gt;

So how can I figure out where DAY_OF is equal to MONTH_OF + 1 and YEAR_OF is equal to DAY_OF + 1? In my head, I thought it would be far more complicated, but it&#39;s not. 

&lt;pre class=&quot;code&quot;&gt;select *
from
(
  select 
    to_number( to_char( sysdate + ( rownum - 1 ), &#39;mm&#39; ) ) month_of,
    to_number( to_char( sysdate + ( rownum - 1 ), &#39;dd&#39; ) ) day_of,
    to_number( to_char( sysdate + ( rownum - 1 ), &#39;yy&#39; ) ) year_of,
    sysdate + ( rownum - 1 ) actual
  from dual
    connect by level &lt;= 100000
)
where &lt;b&gt;month_of + 1 = day_of
  and day_of + 1 = year_of&lt;/b&gt;
order by actual asc&lt;/pre&gt;

Which gives me:

&lt;pre class=&quot;code&quot;&gt;MONTH_OF DAY_OF YEAR_OF ACTUAL   
-------- ------ ------- ----------
11       12     13      2013/11/12 
12       13     14      2014/12/13 
01       02     03      2103/01/02 
02       03     04      2104/02/03 
03       04     05      2105/03/04 
04       05     06      2106/04/05 
05       06     07      2107/05/06 
...&lt;/pre&gt;

OK, so it looks closer to 100 years, not 990. Let&#39;s subtract. LAG to the rescue.

&lt;pre class=&quot;code&quot;&gt;select
  actual,
  lag( actual, 1 ) over ( partition by 1 order by 2 ) previous_actual,
  actual - ( lag( actual, 1 ) over ( partition by 1 order by 2 ) ) time_between
from
(
  select 
    to_number( to_char( sysdate + ( rownum - 1 ), &#39;mm&#39; ) ) month_of,
    to_number( to_char( sysdate + ( rownum - 1 ), &#39;dd&#39; ) ) day_of,
    to_number( to_char( sysdate + ( rownum - 1 ), &#39;yy&#39; ) ) year_of,
    sysdate + ( rownum - 1 ) actual
  from dual
    connect by level &lt;= 100000
)
where month_of + 1 = day_of
  and day_of + 1 = year_of
order by actual asc&lt;/pre&gt;

Which gives me:

&lt;pre class=&quot;code&quot;&gt;ACTUAL     PREVIOUS_ACTUAL TIME_BETWEEN
---------- --------------- ------------
2013/11/12                              
2014/12/13                          396 
2103/01/02                        32161 
2104/02/03                          397 
2105/03/04                          395 
2106/04/05                          397 
2107/05/06                          396 
2108/06/07                          398 
2109/07/08                          396 
2110/08/09                          397 
2111/09/10                          397 
2112/10/11                          397 
2113/11/12                          397 
2114/12/13                          396 
2203/01/02                        32161&lt;/pre&gt;

So, it looks like every 88 years it occurs and is followed by 11 consecutive years of matching numbers. The next time 11/12/13 and 12/13/14 will appear is in 2113 and 2114. Yay for SQL!&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/142980537232715092/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/142980537232715092' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/142980537232715092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/142980537232715092'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2013/11/fun-with-sql-my-birthday.html' title='Fun with SQL - My Birthday'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-2344556600914304690</id><published>2013-10-29T14:36:00.000-04:00</published><updated>2013-10-29T14:37:06.728-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="2013"/><category scheme="http://www.blogger.com/atom/ns#" term="odtug"/><title type='text'>Why I&#39;m voting for Danny Bryant and You Should Too</title><content type='html'>I&#39;m talking about the&amp;nbsp;&lt;a href=&quot;http://www.odtug.com/odtug-board&quot;&gt;ODTUG Board of Directors&lt;/a&gt;. 

&lt;br /&gt;
&lt;br /&gt;
This.
&lt;br /&gt;
&lt;br /&gt;
&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0bAnVtfOSVUYf6t2AVmuhh0W_mFh5n6D7psafeJHThUaHI3FYyP9MVTFDWsPyAQl6pBXygTrNCmjGyo7Wehq4i1-sgPEwHiAGfrykoWgZk3Xt_Dcmy_ngRnxrONB_3hA5IQSnXFBiyQJO/s640/AwcDUvfCIAIdds6.jpg&quot; style=&quot;padding-left: 10px;&quot; /&gt;
&lt;br /&gt;
&lt;br /&gt;
That&#39;s really all you need isn&#39;t it?

&lt;br /&gt;
&lt;br /&gt;

Fine.

&lt;br /&gt;
&lt;br /&gt;

Today wraps up the voting period for the ODTUG Board of Directors. If you&#39;re asking me what ODTUG is, stop reading now. If you are a member of ODTUG, then please give me a few minutes to pontificate (that&#39;s a word I heard &lt;a href=&quot;http://thatjeffsmith.com&quot;&gt;Jeff Smith&lt;/a&gt; use once, hopefully it makes sense here).

&lt;br /&gt;
&lt;br /&gt;

Your favorite Oracle conference, &lt;a href=&quot;http://kscope14.com/&quot;&gt;KScope&lt;/a&gt;, is largely successful based on the efforts of the Board, along with the expert advice of the YCC group. In addition, if you think ODTUG should &quot;do more with Essbase&quot; or &quot;charge more for memberships&quot; these decisions are made and carried out by the board.

&lt;br /&gt;
&lt;br /&gt;

So if you like being in ODTUG, and you want to help it get better and grow, and be as awesome as possible, you only need to do one thing today. &lt;a href=&quot;http://www.odtug.com/2014_election&quot;&gt;Go vote&lt;/a&gt;. Midnight tonight (10/29) is the deadline. &lt;a href=&quot;http://www.youtube.com/watch?v=Ra70O9nps6E&quot;&gt;Do it&lt;/a&gt;.

&lt;br /&gt;
&lt;br /&gt;

You get to vote for several people. I suggest you read their &lt;a href=&quot;http://www.odtug.com/2014_election&quot;&gt;bios&lt;/a&gt;. I&#39;ll save you the time for at least one vote, and that&#39;s for Danny Bryant. 

&lt;br /&gt;
&lt;br /&gt;

Besides that awesome photo (#kscope12 in San Antonio) up above, here are several more reasons. 

&lt;br /&gt;
&lt;br /&gt;

1. He&#39;s into everything. OBIEE. EBS. Essbase. SQL Developer. Database. Not very many people have their hands in everything, he does. He will be able to represent the entire spectrum of ODTUG members.
&lt;br /&gt;
2. He&#39;s a fantastic human being. It&#39;s not just because he takes pictures of himself wearing ORACLENERD gear everywhere (doesn&#39;t hurt though), he&#39;s just, awesome.
&lt;br /&gt;
3. &lt;a href=&quot;https://www.facebook.com/photo.php?fbid=10200297574152537&amp;set=pcb.165633503632563&amp;type=1&amp;theater&quot;&gt;This (Part II)&lt;/a&gt;
&lt;br /&gt;

4. He also always answers the phone, tweets, and emails I send him. He might be sick, or he might just be that responsive. The ODTUG Board member responsibilities will fit nicely on his shoulders I believe.

&lt;br /&gt;
&lt;br /&gt;

So &lt;a href=&quot;http://www.odtug.com/2014_election&quot;&gt;go vote&lt;/a&gt;. Now.

&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/2344556600914304690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/2344556600914304690' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/2344556600914304690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/2344556600914304690'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2013/10/why-im-voting-for-danny-bryant-and-you.html' title='Why I&#39;m voting for Danny Bryant and You Should Too'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0bAnVtfOSVUYf6t2AVmuhh0W_mFh5n6D7psafeJHThUaHI3FYyP9MVTFDWsPyAQl6pBXygTrNCmjGyo7Wehq4i1-sgPEwHiAGfrykoWgZk3Xt_Dcmy_ngRnxrONB_3hA5IQSnXFBiyQJO/s72-c/AwcDUvfCIAIdds6.jpg" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-2457678346382029337</id><published>2013-10-21T20:50:00.000-04:00</published><updated>2013-10-21T20:50:44.188-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="excel"/><category scheme="http://www.blogger.com/atom/ns#" term="obiee"/><category scheme="http://www.blogger.com/atom/ns#" term="vfagundo"/><title type='text'>Excel VS BI in Financial Analysis: why the fight was over before it started</title><content type='html'>&lt;i&gt;by Victor Fagundo&lt;/i&gt;

&lt;br/&gt;&lt;br/&gt;
The argument over why Businesses should abandon Excel in favor of more structured tools has been raging for as long as I have had more than a casual exposure to Oracle products. From the standpoint of an IT user Excel appears to be a simplistic, flat-file-based, error-prone tool that careless people use, despite its obvious flaws. Petabytes of duplicative Excel spreadsheets clog network drives across the globe; we as IT users know it, and it drives us crazy. Why, oh why, can’t these analysts, project managers, and accountants not grasp the elegant beauty of a centralized database solution that ensures data integrity, security, and has the chops to handle gobs of data, and abandon their silly Excel sheets?&lt;br /&gt;
&lt;br /&gt;
I’ll tell you why: Excel is better. Excel the most flexible and feature-rich tool for organizing and analyzing data. Ever. Period.&lt;br /&gt;
&lt;br /&gt;
For the past few years I have lived in a hybrid Finance/IT role, and in coming from IT, I was shocked at how much Excel was used, for everything. But after working with Excel on a daily basis for several years, I am a convert. An adept Excel user can out-develop any tool ( BI, Apex, Hyperion, Crystal Reports ) handily. (when dataset size is not an issue). Microsoft has done too much work on Excel, made it too extendable, too intuitive, built in so much, that no structured tool like BI, APEX, SAP, Hyperion will EVER catch up to its usability/flexibility.&lt;br /&gt;
&lt;br /&gt;
Take this real-world example that came across my desk a few months ago: for a retail chain define a by-week, by-unit sales target, and create a report that compares actual sales to this target. Oh, and the weekly sales targets get adjusted each quarter based on current financial outlook.&lt;br /&gt;
&lt;br /&gt;
How quickly could you turn around a DW/BI solution to this problem? What would it involve?&lt;br /&gt;
• Create table to house targets&lt;br /&gt;
• Create ETL process to load new targets&lt;br /&gt;
• Define BMM/Presentation Layers to expose targets&lt;br /&gt;
• Develop / test / publish report.&lt;br /&gt;
&lt;br /&gt;
A day? Maybe? If one person handled all steps (unlikely, since the DB layers and RPD layers are probably handled by different people.)&lt;br /&gt;
&lt;br /&gt;
I can tell you how long it took me in Excel: 3 hours (OBIEE driven data-dump, married with target sheet supplied to me). I love OBIEE, but Excel was still miles faster/more efficient for this task. And I could regurgitate 6 other examples like this one off at a moment’s notice.&lt;br /&gt;
&lt;br /&gt;
Case in point: 95% of the data that C-level executives use to make strategic decisions is Excel based.&lt;br /&gt;
&lt;br /&gt;
If you’ve ever sat in on a presentation to a CEO or other C-level executive at any medium to large sized company, you know that people are not bringing up dashboards, or any other applications. They are presenting PowerPoints with a few (less than 7) carefully massaged facts on them. If you trace the source of these numbers back down the rabbit hole, your first stop is always Excel. Within these Excel workbooks you will find “guesses” and “plugs” that fill gaps in solid data, to arrive at an actionable bit of information. It’s these “guesses” and “plugs” that are very hard to code for in an environment like OBIEE &amp;nbsp;(or any other application). Can it be done? Yes, of course, with gobs of time and money. And during the fitful and tense development, the creditably of the application is going to take major hits.&lt;br /&gt;
&lt;br /&gt;
Given the above, the usefulness of OBIEE might seem bleak. But I strongly feel that applications such as OBIEE do have a proper place in the upper organizational layers of modern business: Facilitating the Tactical business layers, and providing data-dumps to the Strategic Business layers.&lt;br /&gt;
&lt;br /&gt;
Since this post is mainly about Excel, I will focus on how OBIEE can support the analyses that are inevitably going to be done in Excel.&lt;br /&gt;
&lt;br /&gt;
Data Formatting, Data Formatting, FORMATTING!! I can’t stress this enough. For an analyst, having to re-format numbers that come out of an export so that you can properly display them or drive calcs off them in Excel is infuriating, and wasteful. &amp;nbsp;My favorite examples: in a BI environment I worked with percentages were exported as TEXT, so while they looked fine in the application, as soon as you exported them to Excel and built calcs off them, your answer was overstated by a factor of 100 (Excel understood “75%” to be the number 75 with a text character appended, not the number 0.75).&lt;br /&gt;
&lt;br /&gt;
Ask your users how they would like to SEE a fact in Excel: with decimals or not? &amp;nbsp;With commas or not? Ensure that when exported to Excel, facts and attributes function correctly.&lt;br /&gt;
&lt;br /&gt;
“Pull” refreshes of information sources in Excel. In the finance world, most Excel workbooks are low to medium complexity financial models, based off a data-dump from a reporting system. When the user wants to refresh the model, they refresh the data-dump, and the Excel calculations do the rest. OBIEE currently forces a user to “push” a new data-dump by manually running/exporting from OBIEE and then pasting the data into the data-dump tab in the workbook. What an Excel user really desires is to have a data dump that can be refreshed automatedly, using values that exist on other parts of the workbook to define filters &amp;nbsp;of data-dump. Then all the user needs to do is trigger a “pull” and everything else is automated. Currently OBIEE has no solution to this problem that is elegant enough for the common Excel user. (Smartview must have its filters defined explicitly in the Smartview UI each time an analysis is pulled.)&lt;br /&gt;
&lt;br /&gt;
The important part to take away from these 2 suggestions, and this entire post, is that to maximize the audience of OBIEE, we must acknowledge that Excel is the preferred tool of the Finance department, due to its flexibility, and support friendly exports to Excel as a best practice. We must also understand that accounting for this flexibility in OBIEE is daunting, and probably not the best use of the tool. If your users are asking for a highly complex attribute or fact, that is fraught with exceptions and estimations, chances are they are going to be much happier if what you give them is reliable information in a data-dump form, and allow them to handle the exceptions and estimations in Excel.&lt;br /&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/2457678346382029337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/2457678346382029337' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/2457678346382029337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/2457678346382029337'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2013/10/excel-vs-bi-in-financial-analysis-why.html' title='Excel VS BI in Financial Analysis: why the fight was over before it started'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-365850825859461911</id><published>2013-09-16T22:41:00.000-04:00</published><updated>2013-09-16T22:42:23.887-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="2013"/><category scheme="http://www.blogger.com/atom/ns#" term="oow"/><title type='text'>#OOW13</title><content type='html'>I&#39;m going to be busy.

&lt;br /&gt;&lt;br /&gt;

Here&#39;s my list of events:

&lt;br /&gt;&lt;br /&gt;

&lt;ul&gt;
  &lt;li&gt;Saturday
    &lt;ul&gt;
      &lt;li&gt;I arrive in San Francisco on Saturday around 1 PM. If you&#39;re arriving at around the same time, let me know, we can share a cab into the city.&lt;/li&gt;
      &lt;li&gt;Beer. After arriving I plan on finding a very cold &lt;a href=&quot;http://russianriverbrewing.com/brews/pliny-the-elder/&quot;&gt;Pliny the Elder&lt;/a&gt;. Or three.&lt;/li&gt;
      &lt;li&gt;ODTUG Dinner. I&#39;m crashing this one. It&#39;s Board members only to my knowledge and until someone says I cannot go (especially if fueled by more than one Pliny the Elder), I&#39;m going.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Sunday
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.facebook.com/events/202355076600435/&quot;&gt;Open World Bridge Run&lt;/a&gt;. Not sure if I can make it, but I&#39;m going to try. I&#39;m presenting at 10:15 so it will be a tough decision.&lt;/li&gt;
      &lt;li&gt;10:30 to 11:30. &lt;a href=&quot;https://oracleus.activeevents.com/2013/connect/sessionDetail.ww?SESSION_ID=10009&quot;&gt;Thinking Clearly About Performance&lt;/a&gt;. Somehow I managed to con &lt;a href=&quot;https://twitter.com/CaryMillsap&quot;&gt;Cary Millsap&lt;/a&gt; into a duet of sorts. I have him convinced it is the other way around. Either way, it should be fun (I am not nervous!).&lt;/li&gt;
      &lt;li&gt;2:15 to 4:30, Software Development in the Oracle Ecosystem, &lt;a href=&quot;https://oracleus.activeevents.com/2013/connect/sessionDetail.ww?SESSION_ID=9932&quot;&gt;Part I&lt;/a&gt; and &lt;a href=&quot;https://oracleus.activeevents.com/2013/connect/sessionDetail.ww?SESSION_ID=9948&quot;&gt;Part II&lt;/a&gt;. I&#39;m moderating the aforementioned Mr. Millsap, &lt;a href=&quot;https://twitter.com/stenvesterli&quot;&gt;Sten Vesterli&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/myfear&quot;&gt;Markus Eisele&lt;/a&gt; and &lt;a href=&quot;http://www.linkedin.com/pub/jerry-brenner/0/40/b86&quot;&gt;Jerry Brenner&lt;/a&gt; (My first boss was scheduled to speak as well, but he had a last minute change of plans, jerk).&lt;/li&gt;
      &lt;li&gt;Oracle ACE Dinner. Evening.&lt;/li&gt;
      &lt;li&gt;Post Oracle ACE Dinner drinks...wherever the night takes me.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Monday
    &lt;ul&gt;
      &lt;li&gt;Oracle OpenWorld - San Francisco Bay Swim - Part II, 7:30 AM. We had almost 20 last year, 33 have signed up (on the page anyway) this year. Come along. Cool t-shirts too, sponsored by &lt;a href=&quot;http://www.oracle.com/technetwork/index.html&quot;&gt;Oracle Technology Network&lt;/a&gt; and designed by &lt;a href=&quot;http://www.linkedin.com/pub/lauren-prezby/14/246/59b&quot;&gt;Lauren Prezby&lt;/a&gt;.

&lt;br /&gt;&lt;br /&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfbEvhKhbAqy_RLHWC7lz4ZCeu4f6T1wJoCKTwPW7VvYfgyMxYINCIHOoLI4yv8gBN1GC5cJ2iKrUufea1w6NfqWvAbkSiY88ACP_ni5vRPYquvxROLi12XS1NWvGns3WgrW_Jf43FgFs/s1600/swim_shirts.png&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfbEvhKhbAqy_RLHWC7lz4ZCeu4f6T1wJoCKTwPW7VvYfgyMxYINCIHOoLI4yv8gBN1GC5cJ2iKrUufea1w6NfqWvAbkSiY88ACP_ni5vRPYquvxROLi12XS1NWvGns3WgrW_Jf43FgFs/s320/swim_shirts.png&quot; /&gt;&lt;/a&gt;

&lt;br /&gt;&lt;br /&gt;

Let&#39;s not forget the swim caps! Sponsored by the encouragable &lt;a href=&quot;https://twitter.com/brost&quot;&gt;Bjoern Rost&lt;/a&gt; of The &lt;a href=&quot;http://portrix-systems.de/&quot;&gt;portrix group&lt;/a&gt; (he&#39;s like me, afraid of capital letters) (designed by Lauren Prezby).

&lt;br /&gt;&lt;br /&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihZPmQm-rYPVMtI5lQXJduboOLl6Usw58CAGbNTdGET3cWEMtkgQYJS1iRxYjJyyeWu-rhOTU-7ozRqoltoQRAwQ51XiWpyg7DkMnalETruLkTyYeSNK3frwgRRHYqqv3QGoRCwIxjP_g/s1600/1238833_10200164954677133_1587862987_n.jpg&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihZPmQm-rYPVMtI5lQXJduboOLl6Usw58CAGbNTdGET3cWEMtkgQYJS1iRxYjJyyeWu-rhOTU-7ozRqoltoQRAwQ51XiWpyg7DkMnalETruLkTyYeSNK3frwgRRHYqqv3QGoRCwIxjP_g/s320/1238833_10200164954677133_1587862987_n.jpg&quot; /&gt;&lt;/a&gt;

      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://www.kylehailey.com/oaktable-world/&quot;&gt;Oaktable World&lt;/a&gt;. You&#39;ll most likely catch me here after the swim and before the...&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.facebook.com/events/175411045980422/&quot;&gt;Wear Your ORACLENERD Gear Day&lt;/a&gt;, 3 PM to 4:30 PM. We&#39;ll be taking a group photo around 4:30 PM. If you can&#39;t make it for that, come by when you can and get a picture with me. You know I like that sh...stuff. You don&#39;t have a shirt/hat/sticker/random-item? OTN Lounge is giving away one hundred cool red t-shirts (Lauren Prezby, again).

&lt;br /&gt;&lt;br /&gt;

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKym5byeY1OC-7-LH-qYsUY82ooW3w8khm2OUnHPoTWxJsS22lGn62tTo6x8A0mGyfwSszNZNVeJmmJfxhNKkXAvnj2RuxZjUs6H8OnVcofJ09QakeZtXhIsURQUDN0VY63ScLuwDnF7A/s1600/1267567_10200173693295593_1519911008_o.jpg&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKym5byeY1OC-7-LH-qYsUY82ooW3w8khm2OUnHPoTWxJsS22lGn62tTo6x8A0mGyfwSszNZNVeJmmJfxhNKkXAvnj2RuxZjUs6H8OnVcofJ09QakeZtXhIsURQUDN0VY63ScLuwDnF7A/s320/1267567_10200173693295593_1519911008_o.jpg&quot; /&gt;&lt;/a&gt;

&lt;br /&gt;&lt;br /&gt;

This picture is coinciding with the APEX Developer Challenge which goes from 3 - 7:30 that afternoon/evening. I might even give it a go (fueled, hopefully, by Pliny the Elder).

&lt;/li&gt;
    &lt;/ul&gt;
  &lt;li&gt;Tuesday
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;http://www.kylehailey.com/oaktable-world/&quot;&gt;Oaktable World&lt;/a&gt;.&lt;/li&gt;
      &lt;li&gt;Leave at noon.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

Somewhere in there I&#39;ll get a chance to breathe. I&#39;ll also attend some sessions, hopefully. 
&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/365850825859461911/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/365850825859461911' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/365850825859461911'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/365850825859461911'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2013/09/oow13.html' title='#OOW13'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfbEvhKhbAqy_RLHWC7lz4ZCeu4f6T1wJoCKTwPW7VvYfgyMxYINCIHOoLI4yv8gBN1GC5cJ2iKrUufea1w6NfqWvAbkSiY88ACP_ni5vRPYquvxROLi12XS1NWvGns3WgrW_Jf43FgFs/s72-c/swim_shirts.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-9079694891246769469</id><published>2013-08-26T17:01:00.001-04:00</published><updated>2013-08-26T17:17:10.653-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="dba"/><category scheme="http://www.blogger.com/atom/ns#" term="developer"/><title type='text'>DBA or Developer?</title><content type='html'>I&#39;ve always considered myself a developer and a &lt;span class=&quot;code&quot;&gt;LOWER(DBA)&lt;/span&gt;. I may have recovered perhaps one database and that was &lt;a href=&quot;http://www.oraclenerd.com/2009/09/learning-bybreaking.html&quot;&gt;just a sandbox&lt;/a&gt;, nothing production worthy. I&#39;ve built out instances for development and testing and I&#39;ve installed the software a few hundred times, at least. I&#39;ve done DBA-like duties, but I just don&#39;t think of myself that way. I&#39;m a power developer maybe? Whatevs.

&lt;br /&gt;&lt;br /&gt;

I&#39;m sure it would be nearly impossible to come up with &lt;b&gt;One True Definition of The DBA &amp;#8482;&lt;/b&gt;. So I won&#39;t.

&lt;br /&gt;&lt;br /&gt;

I&#39;ve read that &lt;a href=&quot;http://asktom.oracle.com/pls/apex/f?p=100:1:0&quot;&gt;Tom Kyte&lt;/a&gt; does not consider himself a DBA, but I&#39;m not sure most people know that. From Mr. Kyte himself:

&lt;br /&gt;&lt;br /&gt;

&lt;iframe style=&quot;padding-left: 25px;&quot; width=&quot;420&quot; height=&quot;315&quot; src=&quot;//www.youtube.com/embed/vE9zjPLBMiI?rel=0&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;

&lt;br /&gt;&lt;br /&gt;

At the same conference, I asked &lt;a href=&quot;http://method-r.com/component/content/article/58-biographies/70-cary-millsap&quot;&gt;Cary Millsap&lt;/a&gt; the same question:

&lt;br /&gt;&lt;br /&gt;

&lt;iframe style=&quot;padding-left: 25px;&quot; width=&quot;420&quot; height=&quot;315&quot; src=&quot;//www.youtube.com/embed/luCzsQq8tw4?rel=0&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;

&lt;br /&gt;&lt;br /&gt;

I read Cary for years and always assumed he was a DBA. I mean, have you read his papers? Have you read &lt;i&gt;&lt;a href=&quot;http://www.amazon.com/gp/product/059600527X/ref=as_li_ss_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=059600527X&amp;linkCode=as2&amp;tag=o0430-20&quot;&gt;Optimizing Oracle Performance&lt;/a&gt;&lt;/i&gt;? Performance? That&#39;s what DBAs do (or so I used to think)!

&lt;br /&gt;&lt;br /&gt;

It was only after working with him at #kscope11 on the Building Better Software track that I learned otherwise. 

&lt;br /&gt;&lt;br /&gt;

Perhaps I&#39;ll make this a standard interview question in the future...

&lt;br /&gt;&lt;br /&gt;

Semi-related discussions:

&lt;br /&gt;&lt;br /&gt;
1. &lt;a href=&quot;http://www.oraclenerd.com/2008/02/application-developers-vs-database.html&quot;&gt;Application Developers vs. Database Developers&lt;/a&gt;
&lt;br /&gt;
2. &lt;a href=&quot;http://www.oraclenerd.com/2008/12/application-developers-vs-database.html&quot;&gt;Application Developers vs. Database Developers: Part II&lt;/a&gt;
 &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/9079694891246769469/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/9079694891246769469' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/9079694891246769469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/9079694891246769469'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2013/08/dba-or-developer.html' title='DBA or Developer?'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-3877897024678380198</id><published>2013-08-13T16:24:00.002-04:00</published><updated>2013-08-13T16:24:24.703-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="howto"/><category scheme="http://www.blogger.com/atom/ns#" term="obiee"/><category scheme="http://www.blogger.com/atom/ns#" term="presentation"/><category scheme="http://www.blogger.com/atom/ns#" term="vfagundo"/><title type='text'>Conditional Formatting of Calculated Items in OBIEE 11g</title><content type='html'>&lt;b&gt;&lt;i&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;By Victor Fagundo&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;

&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Calculated items in OBIEE Pivot tables can be very useful in certain reporting circumstances, either for ease of development, or to meet specific report requirements. While calculated items in OBIEE are easy, and flexible, they do have one important drawback: they take on the data and display formatting of the fact column they are calculated against.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
The most common case is the calculation of a % change across a time dimension in financial reporting ( Year over Year, Quarter over Quarter, etc.).&amp;nbsp;&lt;sup&gt;&lt;a href=&quot;#footnote1&quot;&gt;1&lt;/a&gt; &amp;nbsp;&amp;nbsp;&lt;/sup&gt;This type of calculation usually takes the form of a percent change calculation similar to below:&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;pre class=&quot;code&quot;&gt;&amp;nbsp;&lt;span style=&quot;text-indent: 0.5in;&quot;&gt;(( $2 - $1 ) / $1) *100 &lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;text-indent: 0.5in;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
By default, if you perform this calculation against a numerical fact ( sales, customers) you will run into the problem of how to display the % change in the correct format, since the calculated % will want to take the form of the fact it is calculated against, as can be seen in the example&amp;nbsp;&lt;sup&gt;&lt;a href=&quot;#footnote2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&amp;nbsp;below:&lt;br /&gt;
&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYwe8e_ld2gvwe-Z0L9sCIpkcO-2-1RcnvVWMZP7FuwRi3Gqc1f58RwtjTyRbb5STQFLgqjI7DFp1Vrb_wqPTN7S6Bnk9a5G9RQi6gP2ZW8fZiLpRMFCro4kl2wWSFYBRQIwOJuIz7dmhm/s800/Fig%25201.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;125&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYwe8e_ld2gvwe-Z0L9sCIpkcO-2-1RcnvVWMZP7FuwRi3Gqc1f58RwtjTyRbb5STQFLgqjI7DFp1Vrb_wqPTN7S6Bnk9a5G9RQi6gP2ZW8fZiLpRMFCro4kl2wWSFYBRQIwOJuIz7dmhm/s800/Fig%25201.jpg&quot; width=&quot;600&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Figure 1 - Pivot Table&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;&lt;br /&gt;

&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYH8R2IQ7GJPHvnRRlnqemnh3bzgB-pDg5SM6xdCch2GigozcJ7-YnJy0v8vjSNcptYaAqCVoL91t3PQBhfUc9p1nTP4DMhGqYZ5MT471NNrV8fSIQvKu673jhZLV_rrxQTZ5AgRVoONI/s800/Fig%25202.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear:left; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;350&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYH8R2IQ7GJPHvnRRlnqemnh3bzgB-pDg5SM6xdCch2GigozcJ7-YnJy0v8vjSNcptYaAqCVoL91t3PQBhfUc9p1nTP4DMhGqYZ5MT471NNrV8fSIQvKu673jhZLV_rrxQTZ5AgRVoONI/s800/Fig%25202.jpg&quot; width=&quot;600&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Figure 2 - Calculated item&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;br /&gt;
&lt;br /&gt;

&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy3rcMq6yEkkVPKWCRMriAn8YQcl8SMa4BDjuYg0z_xUUyOl_dy5qy36gz5YbqDf-GhhGIipIx6JviKYB7qyrx2jErhFLMyziEEzNkCcGgPmGUq7ZtiDGhm5BgCAd9s8vP07rlTHpVsEY/s800/Fig%25203.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;122&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy3rcMq6yEkkVPKWCRMriAn8YQcl8SMa4BDjuYg0z_xUUyOl_dy5qy36gz5YbqDf-GhhGIipIx6JviKYB7qyrx2jErhFLMyziEEzNkCcGgPmGUq7ZtiDGhm5BgCAd9s8vP07rlTHpVsEY/s800/Fig%25203.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;&lt;div class=&quot;MsoCaption&quot; style=&quot;margin-left: .5in; text-indent: .5in;&quot;&gt;
Figure 3 - Results&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;


&lt;div class=&quot;MsoNormal&quot;&gt;
Not very pretty at all.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
As people searched for a work around to this problem 3 common solutions have arisen:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://forums.oracle.com/thread/859619&quot; target=&quot;_blank&quot;&gt;Use HTML formatting tricks to “hide” trigger text in the results, then conditionally format off those triggers.&lt;/a&gt; While inventive, as the comments note, this solution falls flat if the report is ever printed, as the PDF engine will pick up and display all of the hidden characters.&lt;br /&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://gerardnico.com/wiki/dat/obiee/presentation_service/obiee_conditionnal_formating_on_pivot&quot; target=&quot;_blank&quot;&gt;Convert the pivot table to a regular table with some complex column formulas.&lt;/a&gt; Very time consuming and cumbersome, would also not solve the requirement of showing the dimension values noted as noted in &lt;a href=&quot;http://www.blogger.com/#footnote1&quot;&gt;Footnote1&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;a href=&quot;https://forums.oracle.com/thread/2391722&quot; target=&quot;_blank&quot;&gt;Convert the calculated result to text and manually add your formatting characters&lt;/a&gt;. I don’t think this actually works since the calculated fields won’t accept logical SQL functions, and this would be very cumbersome.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
Now with 11g providing conditional formatting that allows you to override the default data format, this is possible via the following steps:&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;Add a column that is a COUNT DISTINCT on the dimension that you are calculating across ( in the displayed example, “Time T05 Per Name Year”. This column will serve as your “trigger” to apply your conditional formatting.&lt;br /&gt;&lt;br /&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLTnPTwrjq8oxWrVYWE7tC0xsBjB__jG9zkfmRkRaUXJd8pTSPnx_tLgZvWbz6fmPiOqDAvBuNbSOV3or-ux5CfEubtOA_r6s8GeHSP_-2pKGwv4sC3CovR1vnmvcq8W_5nspvY8VWOPM1/s800/Fig%25204.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;117&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLTnPTwrjq8oxWrVYWE7tC0xsBjB__jG9zkfmRkRaUXJd8pTSPnx_tLgZvWbz6fmPiOqDAvBuNbSOV3or-ux5CfEubtOA_r6s8GeHSP_-2pKGwv4sC3CovR1vnmvcq8W_5nspvY8VWOPM1/s800/Fig%25204.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;&lt;div class=&quot;MsoCaption&quot; style=&quot;margin-left: .5in; text-indent: .5in;&quot;&gt;
Figure &lt;!--[if supportFields]&gt;&lt;span
style=&#39;mso-element:field-begin&#39;&gt;&lt;/span&gt;&lt;span
style=&#39;mso-spacerun:yes&#39;&gt; &lt;/span&gt;SEQ Figure \* ARABIC &lt;span style=&#39;mso-element:
field-separator&#39;&gt;&lt;/span&gt;&lt;![endif]--&gt;4&lt;!--[if supportFields]&gt;&lt;span
style=&#39;mso-element:field-end&#39;&gt;&lt;/span&gt;&lt;![endif]--&gt; - Column Formula&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;br /&gt;

&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;For each of your facts, apply a conditional format that is triggered when the above column value is zero. In the formatting, apply whatever visual and data formats you desire. In this example we will format the data as a percent, with one decimal place.&lt;br /&gt;&lt;br /&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhijofTr_CR-8z7yS9cjUlzCKtRa_E2b4fID-fIOu0rYp86Qn7ImKY3VaR9L6h0qJkAkqhh5wDV9m6OOiJXYeBZ8k6w49__9wgeV331Flb7QDde5n5vAGV8hB1qdyPosPiJHqH0-qNqEsc9/s800/Fig%25205.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;142&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhijofTr_CR-8z7yS9cjUlzCKtRa_E2b4fID-fIOu0rYp86Qn7ImKY3VaR9L6h0qJkAkqhh5wDV9m6OOiJXYeBZ8k6w49__9wgeV331Flb7QDde5n5vAGV8hB1qdyPosPiJHqH0-qNqEsc9/s800/Fig%25205.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Figure 5 - Condition&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;


&lt;br /&gt;&lt;br /&gt;

&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGJ3-8ox9tmMtg8zfmZcXtWm0sd4chBzMFFGW-sh218uTqCqNzv5ZW_WQT2p3HZHE2bLHW6PTM3K9CLnKKVFiMdgPM8OE93wcJtIL2owTBQNZBzzeXUrYpezZZ6Phztk5mUdqpJIappr_Y/s800/Fig%25206.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;255&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGJ3-8ox9tmMtg8zfmZcXtWm0sd4chBzMFFGW-sh218uTqCqNzv5ZW_WQT2p3HZHE2bLHW6PTM3K9CLnKKVFiMdgPM8OE93wcJtIL2owTBQNZBzzeXUrYpezZZ6Phztk5mUdqpJIappr_Y/s800/Fig%25206.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Figure 6 - Format when condition is met&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Exclude the “trigger” column from your pivot view. View your results and be satisfied:&lt;br /&gt;&lt;br /&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj34QBOLB0ujjIfv_4lgwT_mbRnTT7NNmwqORYNepx7MijmwXqWDbEgUg_BfUs0YyncUOJADNgr6LcCKZbNQAzp7YJX5V9OThnKkVeoI_uprb9dkmEuaXAdVxbYvSGWjvaxU7FBEu3VdNlN/s800/Fig%25207.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;113&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj34QBOLB0ujjIfv_4lgwT_mbRnTT7NNmwqORYNepx7MijmwXqWDbEgUg_BfUs0YyncUOJADNgr6LcCKZbNQAzp7YJX5V9OThnKkVeoI_uprb9dkmEuaXAdVxbYvSGWjvaxU7FBEu3VdNlN/s800/Fig%25207.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Figure 7 - Correct formatting of calculated item.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
* &lt;i&gt;Note that this would also allow you to apply visual formatting if you wanted to distinguish this row/column as a total.&lt;/i&gt;
&lt;br /&gt;&lt;br /&gt;

&lt;h2&gt;Why it works&lt;/h2&gt;
The use of conditional formatting that applies a data type as part of the format is a straightforward leap of logic, but what to use as the trigger? Most people will try to use the dimension they have setup the calculation in. However, if you try to use the text description given to the calculated item you will find that the condition is never applied:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;


&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8LmS_Aola8ar3L90ew37DIQHsrsBe1eV-Q6b3OAygxwhgfi8GTupgLD9tU9aDUq-z0iSrD7hDWwIX7smv9OcWdaIiy9hbMlOzfbItGlUiJrbYn1MpNqIJeEVOBPlMCANgM_5fpkpvF_H4/s800/Fig%25208.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;141&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8LmS_Aola8ar3L90ew37DIQHsrsBe1eV-Q6b3OAygxwhgfi8GTupgLD9tU9aDUq-z0iSrD7hDWwIX7smv9OcWdaIiy9hbMlOzfbItGlUiJrbYn1MpNqIJeEVOBPlMCANgM_5fpkpvF_H4/s800/Fig%25208.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Figure 8 - Condition on dimension&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;


&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFEs1oKMGzkSW1Ja96dCOjnzLs_kiEVdf_Ezvq2dl44eDIqa-jGgm6fCVtbKPvo_Z9IWOcU1N-ZJfea5POGxnVu6WS9cULoUKPNy6Pnxn6bKlbI3xNKnLWBYVUxP_x6jtQcusKptz3DCsy/s800/Fig%25209.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;119&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFEs1oKMGzkSW1Ja96dCOjnzLs_kiEVdf_Ezvq2dl44eDIqa-jGgm6fCVtbKPvo_Z9IWOcU1N-ZJfea5POGxnVu6WS9cULoUKPNy6Pnxn6bKlbI3xNKnLWBYVUxP_x6jtQcusKptz3DCsy/s800/Fig%25209.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Figure 9 - Condition never met, format never applied&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;


If you try to setup a filter that is true when the dimension is not in reasonable range of values ( in this example we try to format off all years not in the 2000s ) you will find that your calculated item is skipped as well (this has the added vulnerability of being very explicit):&lt;br /&gt;
&lt;br /&gt;

&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3g9GyRvwQbxbIjsy2clkHVITrqJ8uYqGntV2bDOTlCiSBwBICf7ZDQ9IExFb7hUjbTi7Hr-I-RHfa0Cn0x_Bi8OMvtCaYhAo0bVYUFp-DPMtbKRRKGFZnB_9TFkO2JrNNmFSQvik2yDQ/s800/Fig%252010.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;123&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3g9GyRvwQbxbIjsy2clkHVITrqJ8uYqGntV2bDOTlCiSBwBICf7ZDQ9IExFb7hUjbTi7Hr-I-RHfa0Cn0x_Bi8OMvtCaYhAo0bVYUFp-DPMtbKRRKGFZnB_9TFkO2JrNNmFSQvik2yDQ/s800/Fig%252010.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Figure 10 - Condition on dimension values&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;


&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwQnv3c2eRP_2Wkd_rPw3032IeFHUINZMWTAjDTILhyZlrfWLTmbdW5S827mdeao0e-pzqpAXOO_vZRExlAPS2zEADpiu-Yz0VSinIQLwxvghOXUECYEoT8KnJmeD0wwAEspR8ya1gF1g/s800/Fig%252011.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;108&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwQnv3c2eRP_2Wkd_rPw3032IeFHUINZMWTAjDTILhyZlrfWLTmbdW5S827mdeao0e-pzqpAXOO_vZRExlAPS2zEADpiu-Yz0VSinIQLwxvghOXUECYEoT8KnJmeD0wwAEspR8ya1gF1g/s800/Fig%252011.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Figure 11- Condition never met, format never applied&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;
The reason for all this is that the calculated item “borrows” EACH of the dimension values it operates against. Hence, no matter how inventive your filter is, as long as you are trying to somehow separate the calculated member away from the members it is operating on, you will never succeed. This member “borrowing” is apparent if you add the dimension it operates against to the query a 2nd time, and look at the table view.&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;

&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeol7DDdBWAM1cC0_zHxNInU70tCcITq0YyvDOIlk21TsnPX_wOOyiTV5Q6I57ycC0fg6xVblDy-dAItnZOm2WOOTA2yTjqU9JgVUPNz1Xe3ykGYvp4UnIzHx12uiQKhOnZTIRw5q0Txc/s800/Fig%252012.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;261&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeol7DDdBWAM1cC0_zHxNInU70tCcITq0YyvDOIlk21TsnPX_wOOyiTV5Q6I57ycC0fg6xVblDy-dAItnZOm2WOOTA2yTjqU9JgVUPNz1Xe3ykGYvp4UnIzHx12uiQKhOnZTIRw5q0Txc/s800/Fig%252012.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Figure 12 - Calculated item &quot;borrows&quot; members&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;


But since the “member value” given to the calculated item does not actually exist in the dimension, if you try to perform a count distinct against it, you will always get zero.&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzJTW5WPbzINYnCvExKgqeFqQmoWFIUgxscdIEV-BLs1i44k17aWgWsy_BrjqIzZhndAWxrD6dZWMeoy0J0Mfpt7KQdPc_aGBkn8sbOG1a6axDCqT7yYKyJpSr9gJXrvqog9UAdrldAyQ3/s800/Fig%252013.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;167&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzJTW5WPbzINYnCvExKgqeFqQmoWFIUgxscdIEV-BLs1i44k17aWgWsy_BrjqIzZhndAWxrD6dZWMeoy0J0Mfpt7KQdPc_aGBkn8sbOG1a6axDCqT7yYKyJpSr9gJXrvqog9UAdrldAyQ3/s800/Fig%252013.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Figure 13 - Count distinct against dimension&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;

There is your difference; there is your “trigger.” The rest is basic formatting.
&lt;br /&gt;
&lt;br /&gt;

&lt;span id=&quot;footnote1&quot;&gt;1: &lt;/span&gt; &lt;i&gt;You might suggest that this requirement is better served using column(s) with time series calculations, and you might be right. However, more often than not the user will want to SEE the time periods being compared ( 2012 vs 2011, or 08/07/2012 vs 08/07/2011). When using facts with time series calculations you will only be able to show “this year” vs “last year” since the column heading of the time series calculated fact will always be static. In these cases you will need to use the base fact and a time dimension, along with the solution provided here.&lt;/i&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span id=&quot;footnote2&quot;&gt;2: &lt;/span&gt;&lt;i&gt;All screen shots, and examples used in this post are performed in &lt;a href=&quot;http://www.oracle.com/technetwork/middleware/bi-foundation/obiee-samples-167534.html&quot; target=&quot;_blank&quot;&gt;Sample App V305&lt;/a&gt;. An XML of the final correctly formatted report can be downloaded &lt;a href=&quot;https://docs.google.com/file/d/0B4GW2X8EUcQIV3NwYzgyVDBPcE0/edit?usp=sharing&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/i&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; style=&quot;text-indent: .5in;&quot;&gt;
&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/3877897024678380198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/3877897024678380198' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/3877897024678380198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/3877897024678380198'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2013/08/conditional-formatting-of-calculated.html' title='Conditional Formatting of Calculated Items in OBIEE 11g'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYwe8e_ld2gvwe-Z0L9sCIpkcO-2-1RcnvVWMZP7FuwRi3Gqc1f58RwtjTyRbb5STQFLgqjI7DFp1Vrb_wqPTN7S6Bnk9a5G9RQi6gP2ZW8fZiLpRMFCro4kl2wWSFYBRQIwOJuIz7dmhm/s72-c/Fig%25201.jpg" height="72" width="72"/><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-3761071737289548438</id><published>2013-07-30T23:02:00.002-04:00</published><updated>2013-07-30T23:02:55.911-04:00</updated><title type='text'>Learn To ______ In A Year</title><content type='html'>It started at The &lt;a href=&quot;http://thetalentcode.com/&quot;&gt;Talent Code&lt;/a&gt; blog by Daniel Coyle a few weeks back, &lt;a href=&quot;http://thetalentcode.com/2013/07/01/whats-your-lq-learning-quotient/&quot;&gt;&lt;i&gt;What&#39;s Your LQ (Learning Quotient)?&lt;/i&gt;&lt;/a&gt;. That led me to &lt;a href=&quot;http://www.nytimes.com/2013/07/01/sports/baseball/diamondbacks-goldschmidt-has-little-ego-and-few-limits.html&quot;&gt;&lt;i&gt;Diamondbacks’ Goldschmidt Has Little Ego and Few Limits&lt;/i&gt;&lt;/a&gt;. I like baseball stories. I especially like this passage: 

&lt;br /&gt;&lt;br /&gt;

&lt;div class=&quot;documentation&quot;&gt;“A lot of kids have so much pride that they want to show the coaches and the front office that they know what they’re doing, and they don’t need the help,” Zinter said. “They don’t absorb the information because they want us to think they know it already. Goldy didn’t have an ego. He didn’t have that illusion of knowledge. He’s O.K. with wanting to learn.”&lt;/div&gt;

&lt;br /&gt;

I identify with that. I believe part of my success is because I ask questions.

&lt;br /&gt;&lt;br /&gt;

Back to the original article. Then I end up here, &lt;i&gt;&lt;a href=&quot;http://blogs.kqed.org/mindshift/2011/11/can-everyone-be-smart-at-everything/&quot;&gt;Can Everyone Be Smart at Everything?&lt;/a&gt;&lt;/i&gt; I seem to lack the ability to focus for extended periods of time. Well, not quite true. I have the ability to focus, but I like to focus on a million different things. Does that count? I don&#39;t know. 

&lt;br /&gt;&lt;br /&gt;

I&#39;m often envious of my friends who have been DBAs for 20 years, or worked with OBIEE for 10 years (don&#39;t argue with me...I know Oracle hasn&#39;t owned it for 10 years, I&#39;m looking at you &lt;a href=&quot;https://twitter.com/nephentur&quot;&gt;Christian&lt;/a&gt;), or APEX for 10 years (that&#39;s safe to say). I&#39;ve flirted with all of those, but I&#39;ve never committed...See how I get distracted easily? Wow. 


&lt;br /&gt;&lt;br /&gt;

&lt;div class=&quot;documentation&quot;&gt;And just as importantly, that mistakes are part of good learning. As a Wired article recently reported about why some are more effective at learning from mistakes, “the important part is what happens next.” People with a “growth mindset” — those who “believe that we can get better at almost anything, provided we invest the necessary time and energy” — were significantly better at learning from their mistakes.&lt;/div&gt;

&lt;br /&gt;

and then...

&lt;br /&gt;&lt;br /&gt;

&lt;div class=&quot;documentation&quot;&gt;“The meaning of difficulty changes. Difficulty means trying harder, trying a different strategy. They understand that change is possible, and progress occurs over time.”&lt;/div&gt;

&lt;br /&gt;&lt;br /&gt;

OMFG. Focus!

&lt;br /&gt;&lt;br /&gt;

Back to the original article and I&#39;m reading through the comments. Someone links up to this young lady who taught herself how to &lt;a href=&quot;http://www.danceinayear.com/story/&quot;&gt;dance in a year&lt;/a&gt;. Watch it.

&lt;br /&gt;&lt;br /&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;//www.youtube.com/embed/daC2EPUh22w?rel=0&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;

&lt;br /&gt;&lt;br /&gt;

Which finally brings me back to The Talent Code, &lt;i&gt;&lt;a href=&quot;http://thetalentcode.com/2013/07/18/to-improve-faster-think-like-a-startup/&quot;&gt;To Improve Faster, Think Like a Startup&lt;/a&gt;&lt;/i&gt;. Staying with me? How about this?

&lt;br /&gt;&lt;br /&gt;

&lt;img style=&quot;left-padding: 25px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOHSYyvTBrW0YXaiVhkwYYXNRneXGe0Ijb19VxE-jT2fgM5ZLeLKfssXy-qttzuMaAQwZrQt64k_Zx9zMYKrS_yHehfXr5awAAoOybxmseiTQf4HzrWgKd9QbNCJqaA25i2SN6A0tQ6nQ/s800/the_crazy_loop2.png&quot; /&gt;

&lt;br /&gt;&lt;br /&gt;

Finally, there&#39;s a point. I want to do this. Maybe not dance (as much fun as that may be), but something else. Krav Maga? Algebra? Calculus (I&#39;m pursuing my physics or engineering degree in 2035, I need to study my math). I want to test out her technique. Small, discrete steps practiced daily towards some end goal (pass a calc test, take a real estate licensing test, whatever). The problem for me, if you haven&#39;t noticed, is focus. This method may help.

&lt;br /&gt;&lt;br /&gt;

If you were to try something like this, what would you set out to learn?&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/3761071737289548438/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/3761071737289548438' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/3761071737289548438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/3761071737289548438'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2013/07/learn-to-in-year.html' title='Learn To ______ In A Year'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOHSYyvTBrW0YXaiVhkwYYXNRneXGe0Ijb19VxE-jT2fgM5ZLeLKfssXy-qttzuMaAQwZrQt64k_Zx9zMYKrS_yHehfXr5awAAoOybxmseiTQf4HzrWgKd9QbNCJqaA25i2SN6A0tQ6nQ/s72-c/the_crazy_loop2.png" height="72" width="72"/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8884584404576003487.post-1101726442686425196</id><published>2013-07-08T11:54:00.001-04:00</published><updated>2013-07-08T11:54:25.316-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="howto"/><category scheme="http://www.blogger.com/atom/ns#" term="rant"/><title type='text'>Write It Out</title><content type='html'>This one was sitting in the drafts folder for a week or two, then I saw this post on Twitter:

&lt;br /&gt;

&lt;blockquote class=&quot;twitter-tweet&quot;&gt;&lt;p&gt;I wonder what percentage of people ask a question and figure it out on their own before you help them. What about in your experience?&lt;/p&gt;&amp;mdash; Amy Caldwell (@amyccaldwell) &lt;a href=&quot;https://twitter.com/amyccaldwell/statuses/354257005839519745&quot;&gt;July 8, 2013&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;br /&gt;

Years ago I had a boss who was my technical superior (he may still be). I used to pop in and out of his office, or try to, and ask questions. Most of them were silly, n00b questions.

&lt;br /&gt;&lt;br /&gt;

He was nice, but busy. It didn&#39;t take me very long to &quot;read&quot; that. So I slowed down my pace of questions. I began to write things up via &lt;a href=&quot;http://www.oraclenerd.com/2010/06/why-i-love-email.html&quot;&gt;email&lt;/a&gt; so that he could respond when &lt;i&gt;he&lt;/i&gt; the had time. I started to use forums as well. Then I &lt;strike&gt;found&lt;/strike&gt; was directed to &lt;i&gt;&lt;a href=&quot;http://www.catb.org/esr/faqs/smart-questions.html&quot;&gt;How To Ask Questions The Smart Way&lt;/a&gt;&lt;/i&gt;. 


&lt;br /&gt;&lt;br /&gt;

One of the things that became evident quickly is that I didn&#39;t always have to hit Send (email) or Submit (forum post), just the act of writing it out forced me to think through the issue and more often than not, I would figure out the answer on my own.

&lt;br /&gt;&lt;br /&gt;

Flash forward five or six years and I started to receive all these questions, either in person or via chat. &quot;Send me an email&quot; was usually my response, especially if I was in the middle of something (see: &lt;a href=&quot;http://www.oraclenerd.com/2013/07/context-switching-example.html&quot;&gt;Context Switching&lt;/a&gt;). I was happy to help, just not at that moment. With email, I could get to it when I got a break (or needed one). 

&lt;br /&gt;&lt;br /&gt;

One of my favorite people, Jason Baer, who has worked for RittmanMead for the last couple of years, took this to heart. We started working together in December of 2009 and he would pepper me with questions constantly. I could never keep up. &quot;Email the question Jason.&quot;

&lt;br /&gt;&lt;br /&gt;

I didn&#39;t realize it, but I started getting fewer and fewer emails/questions from him. He began to figure them out on his own. It seemed most of the time he had just missed something, other times he just figured out another way to do something.

&lt;br /&gt;&lt;br /&gt;

Jason is a smart guy. I think I&#39;m smart. Sometimes it&#39;s just easier to ask the question without thinking it through. In fact, I do that quite a bit on The Twitter Machine &amp;#0153;, especially those errors that I seem to know but just don&#39;t have the bandwidth to research (think DBA type questions). I believe the types of questions that &lt;b&gt;&lt;strike&gt;should&lt;/strike&gt;&lt;/b&gt; &lt;b&gt;must&lt;/b&gt; be written down are those that deal with Approach (design, architecture, etc). Any of those ORA errors better come along with a link to the error code in the documentation and some proof that you&#39;ve researched it a bit yourself...but then that&#39;s getting into &lt;i&gt;&lt;a href=&quot;http://www.catb.org/esr/faqs/smart-questions.html&quot;&gt;How To Ask Questions The Smart Way&lt;/a&gt;&lt;/i&gt;.

&lt;br /&gt;&lt;br /&gt;

Go out and practice. Next time you have a (technical) question for someone, anyone, write it down and see what happens.
&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;div&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--google_ad_client = &quot;pub-3853911845992923&quot;;/* atom feed */google_ad_slot = &quot;1428191201&quot;;google_ad_width = 728;google_ad_height = 15;//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.oraclenerd.com/feeds/1101726442686425196/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8884584404576003487/1101726442686425196' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/1101726442686425196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8884584404576003487/posts/default/1101726442686425196'/><link rel='alternate' type='text/html' href='http://www.oraclenerd.com/2013/07/write-it-out.html' title='Write It Out'/><author><name>oraclenerd</name><uri>http://www.blogger.com/profile/12412013306950057961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry></feed>