SlideShare ist ein Scribd-Unternehmen logo
1 von 31
Downloaden Sie, um offline zu lesen
loan_nbr   customer_nbr   code     value
                  1          1              amount   1500.00
                  1          1              date     20080110
                  1          1              type     personal
                  2          2              amount   3500.00
                  2          2              date     20080215
                  2          2              type     personal




CREATE TABLE EAV_Loans (
 loan_nbr INT NOT NULL,
 customer_nbr INT NOT NULL,
 code VARCHAR(30) NOT NULL,
 value VARCHAR(200),
 CONSTRAINT pk_eav_loans
 PRIMARY KEY (loan_nbr, customer_nbr, code));
-- Customers with personal loans over 1000.00 for the period
-- Jan 1, 2008 through Jan 31, 2008

SELECT A.loan_nbr,
       A.customer_nbr,
       CAST(A.value AS DATETIME) AS loan_date,
       CAST(B.value AS DECIMAL(15, 2)) AS loan_amount
FROM EAV_Loans AS A
INNER JOIN EAV_Loans AS B
   ON A.loan_nbr = B.loan_nbr
  AND A.customer_nbr = B.customer_nbr
INNER JOIN EAV_Loans AS C
   ON A.loan_nbr = C.loan_nbr
  AND A.customer_nbr = C.customer_nbr
WHERE A.code = 'date'
  AND CAST(A.value AS DATETIME) >= '20080101'
  AND CAST(A.value AS DATETIME) < '20080201'
  AND B.code = 'amount'
  AND CAST(B.value AS DECIMAL(15, 2)) > 1000.00
  AND C.code = 'type'
  AND C.value = 'personal';
SELECT A.loan_nbr,
       A.customer_nbr,
       loan_date,
       loan_amount
FROM (SELECT loan_nbr, customer_nbr,
             CAST(value AS DATETIME) AS loan_date
      FROM EAV_Loans
      WHERE code = 'date') AS A
INNER JOIN (SELECT loan_nbr, customer_nbr,
                   CAST(value AS DECIMAL(15, 2))
                              AS loan_amount
            FROM EAV_Loans
            WHERE code = 'amount') AS B
   ON A.loan_nbr = B.loan_nbr
  AND A.customer_nbr = B.customer_nbr
INNER JOIN (SELECT loan_nbr, customer_nbr,
                   value AS loan_type
            FROM EAV_Loans
            WHERE code = 'type') AS C
   ON A.loan_nbr = C.loan_nbr
  AND A.customer_nbr = C.customer_nbr
WHERE loan_date >= '20080101'
  AND loan_date < '20080201'
  AND loan_amount > 1000.00
  AND loan_type = 'personal';
SELECT loan_nbr,
        customer_nbr,
        loan_date,
        loan_amount
FROM (SELECT loan_nbr,
              customer_nbr,
              MAX(CASE WHEN code = 'date'
                       THEN CAST(value AS DATETIME) END),
              MAX(CASE WHEN code = 'amount'
                       THEN CAST(value AS DECIMAL(15, 2)) END),
              MAX(CASE WHEN code = 'type'
                       THEN value END)
      FROM EAV_Loans
      GROUP BY loan_nbr, customer_nbr
      )
   AS L(loan_nbr, customer_nbr, loan_date, loan_amount, loan_type)
WHERE loan_date >= '20080101'
  AND loan_date < '20080201'
  AND loan_amount > 1000.00
  AND loan_type = 'personal';
loan_nbr   customer_nbr   loan_date                 loan_amount   loan_type
1          1              2008-01-10 00:00:00.000   1500.00       personal
2          2              2008-02-15 00:00:00.000   3500.00       personal




CREATE TABLE Loans (
 loan_nbr INT NOT NULL,
 customer_nbr INT NOT NULL,
 loan_date DATETIME NOT NULL,
 loan_amount DECIMAL(15, 2) NOT NULL,
 loan_type VARCHAR(10) NOT NULL,
 CONSTRAINT ck_loan_type
 CHECK (loan_type IN ('personal', 'business')),
 CONSTRAINT pk_loans
 PRIMARY KEY (loan_nbr));
-- Convert EAV table to normalized
INSERT INTO Loans
(loan_nbr, customer_nbr, loan_date, loan_amount, loan_type)
SELECT loan_nbr,
       customer_nbr,
       MAX(CASE WHEN code = 'date'
                THEN CAST(value AS DATETIME) END),
       MAX(CASE WHEN code = 'amount'
                THEN CAST(value AS DECIMAL(15, 2)) END),
       MAX(CASE WHEN code = 'type' THEN value END)
FROM EAV_Loans
GROUP BY loan_nbr, customer_nbr;
-- Customers with personal loans over 1000.00
-- for period Jan 1, 2008 through Jan 31, 2008
SELECT loan_nbr, customer_nbr, loan_date, loan_amount
FROM Loans
WHERE loan_date >= '20080101'
  AND loan_date < '20080201'
  AND loan_amount > 1000.00
  AND loan_type = 'personal';
-- Replacement view for legacy code
CREATE VIEW EAV_Loans
(loan_nbr, customer_nbr, code, value)
AS
SELECT loan_nbr, customer_nbr,
       CAST('date' AS VARCHAR(30)),
       CONVERT(VARCHAR(200), loan_date, 112)
FROM Loans
UNION
SELECT loan_nbr, customer_nbr,
       CAST('amount' AS VARCHAR(30)),
       CAST(loan_amount AS VARCHAR(200))
FROM Loans
UNION
SELECT loan_nbr, customer_nbr,
       CAST('type' AS VARCHAR(30)),
       CAST(loan_type AS VARCHAR(200))
FROM Loans;
loan_nbr   loan_date                 loan_amount   loan_type   rk
3          2008-03-11 00:00:00.000   5000.00       business    1
6          2008-03-27 00:00:00.000   4000.00       business    2
7          2008-04-10 00:00:00.000   3500.00       business    3
4          2008-03-12 00:00:00.000   2000.00       personal    1
8          2008-04-12 00:00:00.000   2000.00       personal    2
1          2008-01-01 00:00:00.000   1500.00       personal    3
5          2008-03-25 00:00:00.000   1200.00       personal    4
2          2008-02-15 00:00:00.000   1000.00       personal    5
SELECT loan_nbr, loan_date, loan_amount,
       loan_type,
      (SELECT COUNT(*)
       FROM Loans AS L2
       WHERE L2.loan_type = L1.loan_type
         AND (L2.loan_amount > L1.loan_amount
          OR L2.loan_amount = L1.loan_amount
         AND L2.loan_nbr <= L1.loan_nbr)) AS rk
FROM Loans AS L1
ORDER BY loan_type, rk;
SELECT loan_nbr, loan_date, loan_amount, loan_type,
       ROW_NUMBER() OVER(PARTITION BY loan_type
                         ORDER BY loan_amount DESC,
                                  loan_nbr) AS rk
FROM Loans
ORDER BY loan_type, rk;
loan_nbr   customer_nbr       loan_date                 loan_amount    loan_type
2          2                  2008-02-15 00:00:00.000   1000.00        personal
3          1                  2008-03-11 00:00:00.000   4500.00        business
4          3                  2008-03-12 00:00:00.000   2000.00        personal




               loan_nbr   customer_nbr    loan_date                   loan_amount   loan_type
               1          1               2008-01-01 00:00:00.000     1500.00       personal
               2          2               2008-02-15 00:00:00.000     1000.00       personal
               3          1               2008-03-11 00:00:00.000     5000.00       business




loan_nbr   customer_nbr       loan_date                 loan_amount    loan_type
2          2                  2008-02-15 00:00:00.000   1000.00        personal
3          1                  2008-03-11 00:00:00.000   4500.00        business
4          3                  2008-03-12 00:00:00.000   2000.00        personal
-- Update changed
UPDATE Loans
SET loan_amount = (SELECT D.loan_amount
                   FROM DailyChangedLoans AS D
                   WHERE D.loan_nbr = Loans.loan_nbr
                     AND D.loan_amount <> Loans.loan_amount)
WHERE EXISTS(SELECT *
             FROM DailyChangedLoans AS D
             WHERE D.loan_nbr = Loans.loan_nbr
               AND D.loan_amount <> Loans.loan_amount);

-- Insert new loans
INSERT INTO Loans
(loan_nbr, customer_nbr, loan_date, loan_amount, loan_type)
SELECT loan_nbr,
       customer_nbr,
       loan_date,
       loan_amount,
       loan_type
FROM DailyChangedLoans AS D
WHERE NOT EXISTS(SELECT *
                 FROM Loans AS L
                 WHERE D.loan_nbr = L.loan_nbr);

-- Remove deleted
DELETE FROM Loans
WHERE NOT EXISTS(SELECT *
                 FROM DailyChangedLoans AS D
                 WHERE D.loan_nbr = Loans.loan_nbr);
-- Using a single MERGE statement
MERGE INTO Loans AS L
USING DailyChangedLoans AS D
   ON D.loan_nbr = L.loan_nbr
WHEN MATCHED
 AND L.loan_amount <> D.loan_amount
THEN UPDATE SET loan_amount = D.loan_amount
WHEN NOT MATCHED
THEN INSERT VALUES(D.loan_nbr,
                   D.customer_nbr,
                   D.loan_date,
                   D.loan_amount,
                   D.loan_type)
WHEN NOT MATCHED BY SOURCE
THEN DELETE;
loan_nbr   customer_nbr   loan_date                  loan_amount   loan_type
1          1              2008-01-01 00:00:00.000    1500.00       personal
2          2              2008-01-02 00:00:00.000    1000.00       personal
3          1              2008-01-03 00:00:00.000    5000.00       business
4          3              2008-01-12 00:00:00.000    2000.00       personal
5          4              2008-01-13 00:00:00.000    1200.00       personal
6          3              2008-01-29 00:00:00.000    4000.00       business
7          5              2008-01-30 00:00:00.000    3500.00       business
8          2              2008-01-31 00:00:00.000    2000.00       personal




                           start_date                 end_date
                           2008-01-01 00:00:00.000    2008-01-03 00:00:00.000
                           2008-01-12 00:00:00.000    2008-01-13 00:00:00.000
                           2008-01-29 00:00:00.000    2008-01-31 00:00:00.000
-- Find last date for date range
-- and use as grouping factor

SELECT MIN(loan_date) AS start_date,
       MAX(loan_date) AS end_date
FROM (SELECT loan_date,
            (SELECT MIN(L2.loan_date)
             FROM Loans AS L2
             WHERE L2.loan_date >= L1.loan_date
               AND NOT EXISTS
                  (SELECT *
                   FROM Loans AS L3
                   WHERE L3.loan_date =
                         DATEADD(DAY, 1, L2.loan_date))
             ) AS base
      FROM Loans AS L1) AS L
GROUP BY base;
-- Preparation for solution
SELECT loan_date,
       DATEDIFF(DAY, '19000101', loan_date) AS days_since_base_date,
       ROW_NUMBER() OVER(ORDER BY loan_date) AS rn
FROM Loans;


              loan_date                 days_since_base_date   rn
              2008-01-01 00:00:00.000   39446                  1
              2008-01-02 00:00:00.000   39447                  2
              2008-01-03 00:00:00.000   39448                  3
              2008-01-12 00:00:00.000   39457                  4
              2008-01-13 00:00:00.000   39458                  5
              2008-01-29 00:00:00.000   39474                  6
              2008-01-30 00:00:00.000   39475                  7
              2008-01-31 00:00:00.000   39476                  8
-- Solution with ROW_NUMBER
SELECT MIN(loan_date) AS start_date,
       MAX(loan_date) AS end_date
FROM (SELECT loan_date,
             DATEDIFF(DAY, '19000101', loan_date) -
             ROW_NUMBER() OVER(ORDER BY loan_date) AS base
      FROM Loans) AS L
GROUP BY base;
Refactoring SQL for Performance
Refactoring SQL for Performance

Weitere ähnliche Inhalte

Ähnlich wie Refactoring SQL for Performance

Single Message Transforms (SMT) in Kafka Connect | Betül Çetinkaya and Okan Y...
Single Message Transforms (SMT) in Kafka Connect | Betül Çetinkaya and Okan Y...Single Message Transforms (SMT) in Kafka Connect | Betül Çetinkaya and Okan Y...
Single Message Transforms (SMT) in Kafka Connect | Betül Çetinkaya and Okan Y...HostedbyConfluent
 
Project 01 - Data Exploration and Reporting
Project 01 - Data Exploration and ReportingProject 01 - Data Exploration and Reporting
Project 01 - Data Exploration and ReportingAmarnathVenkataraman
 
GPUG Academy: Microsoft Excel and Microsoft Dynamics Receivables Management
GPUG Academy:  Microsoft Excel and Microsoft Dynamics Receivables ManagementGPUG Academy:  Microsoft Excel and Microsoft Dynamics Receivables Management
GPUG Academy: Microsoft Excel and Microsoft Dynamics Receivables ManagementBelinda Allen
 
[DSC Europe 23][Cryptica] Jovan_Milovanovic-Bank_Statement_Data_Analysis.pdf
[DSC Europe 23][Cryptica] Jovan_Milovanovic-Bank_Statement_Data_Analysis.pdf[DSC Europe 23][Cryptica] Jovan_Milovanovic-Bank_Statement_Data_Analysis.pdf
[DSC Europe 23][Cryptica] Jovan_Milovanovic-Bank_Statement_Data_Analysis.pdfDataScienceConferenc1
 
GPUG Academy - Microsoft Excel & Microsoft Dynamics GP Payables Management (M...
GPUG Academy - Microsoft Excel & Microsoft Dynamics GP Payables Management (M...GPUG Academy - Microsoft Excel & Microsoft Dynamics GP Payables Management (M...
GPUG Academy - Microsoft Excel & Microsoft Dynamics GP Payables Management (M...Belinda Allen
 
Subscribed 2017: Building a Data Pipeline to Engage and Retain Your Subscribers
Subscribed 2017: Building a Data Pipeline to Engage and Retain Your SubscribersSubscribed 2017: Building a Data Pipeline to Engage and Retain Your Subscribers
Subscribed 2017: Building a Data Pipeline to Engage and Retain Your SubscribersZuora, Inc.
 

Ähnlich wie Refactoring SQL for Performance (6)

Single Message Transforms (SMT) in Kafka Connect | Betül Çetinkaya and Okan Y...
Single Message Transforms (SMT) in Kafka Connect | Betül Çetinkaya and Okan Y...Single Message Transforms (SMT) in Kafka Connect | Betül Çetinkaya and Okan Y...
Single Message Transforms (SMT) in Kafka Connect | Betül Çetinkaya and Okan Y...
 
Project 01 - Data Exploration and Reporting
Project 01 - Data Exploration and ReportingProject 01 - Data Exploration and Reporting
Project 01 - Data Exploration and Reporting
 
GPUG Academy: Microsoft Excel and Microsoft Dynamics Receivables Management
GPUG Academy:  Microsoft Excel and Microsoft Dynamics Receivables ManagementGPUG Academy:  Microsoft Excel and Microsoft Dynamics Receivables Management
GPUG Academy: Microsoft Excel and Microsoft Dynamics Receivables Management
 
[DSC Europe 23][Cryptica] Jovan_Milovanovic-Bank_Statement_Data_Analysis.pdf
[DSC Europe 23][Cryptica] Jovan_Milovanovic-Bank_Statement_Data_Analysis.pdf[DSC Europe 23][Cryptica] Jovan_Milovanovic-Bank_Statement_Data_Analysis.pdf
[DSC Europe 23][Cryptica] Jovan_Milovanovic-Bank_Statement_Data_Analysis.pdf
 
GPUG Academy - Microsoft Excel & Microsoft Dynamics GP Payables Management (M...
GPUG Academy - Microsoft Excel & Microsoft Dynamics GP Payables Management (M...GPUG Academy - Microsoft Excel & Microsoft Dynamics GP Payables Management (M...
GPUG Academy - Microsoft Excel & Microsoft Dynamics GP Payables Management (M...
 
Subscribed 2017: Building a Data Pipeline to Engage and Retain Your Subscribers
Subscribed 2017: Building a Data Pipeline to Engage and Retain Your SubscribersSubscribed 2017: Building a Data Pipeline to Engage and Retain Your Subscribers
Subscribed 2017: Building a Data Pipeline to Engage and Retain Your Subscribers
 

Kürzlich hochgeladen

Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 

Kürzlich hochgeladen (20)

Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 

Refactoring SQL for Performance

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6. loan_nbr customer_nbr code value 1 1 amount 1500.00 1 1 date 20080110 1 1 type personal 2 2 amount 3500.00 2 2 date 20080215 2 2 type personal CREATE TABLE EAV_Loans ( loan_nbr INT NOT NULL, customer_nbr INT NOT NULL, code VARCHAR(30) NOT NULL, value VARCHAR(200), CONSTRAINT pk_eav_loans PRIMARY KEY (loan_nbr, customer_nbr, code));
  • 7. -- Customers with personal loans over 1000.00 for the period -- Jan 1, 2008 through Jan 31, 2008 SELECT A.loan_nbr, A.customer_nbr, CAST(A.value AS DATETIME) AS loan_date, CAST(B.value AS DECIMAL(15, 2)) AS loan_amount FROM EAV_Loans AS A INNER JOIN EAV_Loans AS B ON A.loan_nbr = B.loan_nbr AND A.customer_nbr = B.customer_nbr INNER JOIN EAV_Loans AS C ON A.loan_nbr = C.loan_nbr AND A.customer_nbr = C.customer_nbr WHERE A.code = 'date' AND CAST(A.value AS DATETIME) >= '20080101' AND CAST(A.value AS DATETIME) < '20080201' AND B.code = 'amount' AND CAST(B.value AS DECIMAL(15, 2)) > 1000.00 AND C.code = 'type' AND C.value = 'personal';
  • 8.
  • 9. SELECT A.loan_nbr, A.customer_nbr, loan_date, loan_amount FROM (SELECT loan_nbr, customer_nbr, CAST(value AS DATETIME) AS loan_date FROM EAV_Loans WHERE code = 'date') AS A INNER JOIN (SELECT loan_nbr, customer_nbr, CAST(value AS DECIMAL(15, 2)) AS loan_amount FROM EAV_Loans WHERE code = 'amount') AS B ON A.loan_nbr = B.loan_nbr AND A.customer_nbr = B.customer_nbr INNER JOIN (SELECT loan_nbr, customer_nbr, value AS loan_type FROM EAV_Loans WHERE code = 'type') AS C ON A.loan_nbr = C.loan_nbr AND A.customer_nbr = C.customer_nbr WHERE loan_date >= '20080101' AND loan_date < '20080201' AND loan_amount > 1000.00 AND loan_type = 'personal';
  • 10. SELECT loan_nbr, customer_nbr, loan_date, loan_amount FROM (SELECT loan_nbr, customer_nbr, MAX(CASE WHEN code = 'date' THEN CAST(value AS DATETIME) END), MAX(CASE WHEN code = 'amount' THEN CAST(value AS DECIMAL(15, 2)) END), MAX(CASE WHEN code = 'type' THEN value END) FROM EAV_Loans GROUP BY loan_nbr, customer_nbr ) AS L(loan_nbr, customer_nbr, loan_date, loan_amount, loan_type) WHERE loan_date >= '20080101' AND loan_date < '20080201' AND loan_amount > 1000.00 AND loan_type = 'personal';
  • 11. loan_nbr customer_nbr loan_date loan_amount loan_type 1 1 2008-01-10 00:00:00.000 1500.00 personal 2 2 2008-02-15 00:00:00.000 3500.00 personal CREATE TABLE Loans ( loan_nbr INT NOT NULL, customer_nbr INT NOT NULL, loan_date DATETIME NOT NULL, loan_amount DECIMAL(15, 2) NOT NULL, loan_type VARCHAR(10) NOT NULL, CONSTRAINT ck_loan_type CHECK (loan_type IN ('personal', 'business')), CONSTRAINT pk_loans PRIMARY KEY (loan_nbr));
  • 12. -- Convert EAV table to normalized INSERT INTO Loans (loan_nbr, customer_nbr, loan_date, loan_amount, loan_type) SELECT loan_nbr, customer_nbr, MAX(CASE WHEN code = 'date' THEN CAST(value AS DATETIME) END), MAX(CASE WHEN code = 'amount' THEN CAST(value AS DECIMAL(15, 2)) END), MAX(CASE WHEN code = 'type' THEN value END) FROM EAV_Loans GROUP BY loan_nbr, customer_nbr;
  • 13. -- Customers with personal loans over 1000.00 -- for period Jan 1, 2008 through Jan 31, 2008 SELECT loan_nbr, customer_nbr, loan_date, loan_amount FROM Loans WHERE loan_date >= '20080101' AND loan_date < '20080201' AND loan_amount > 1000.00 AND loan_type = 'personal';
  • 14. -- Replacement view for legacy code CREATE VIEW EAV_Loans (loan_nbr, customer_nbr, code, value) AS SELECT loan_nbr, customer_nbr, CAST('date' AS VARCHAR(30)), CONVERT(VARCHAR(200), loan_date, 112) FROM Loans UNION SELECT loan_nbr, customer_nbr, CAST('amount' AS VARCHAR(30)), CAST(loan_amount AS VARCHAR(200)) FROM Loans UNION SELECT loan_nbr, customer_nbr, CAST('type' AS VARCHAR(30)), CAST(loan_type AS VARCHAR(200)) FROM Loans;
  • 15.
  • 16.
  • 17. loan_nbr loan_date loan_amount loan_type rk 3 2008-03-11 00:00:00.000 5000.00 business 1 6 2008-03-27 00:00:00.000 4000.00 business 2 7 2008-04-10 00:00:00.000 3500.00 business 3 4 2008-03-12 00:00:00.000 2000.00 personal 1 8 2008-04-12 00:00:00.000 2000.00 personal 2 1 2008-01-01 00:00:00.000 1500.00 personal 3 5 2008-03-25 00:00:00.000 1200.00 personal 4 2 2008-02-15 00:00:00.000 1000.00 personal 5
  • 18. SELECT loan_nbr, loan_date, loan_amount, loan_type, (SELECT COUNT(*) FROM Loans AS L2 WHERE L2.loan_type = L1.loan_type AND (L2.loan_amount > L1.loan_amount OR L2.loan_amount = L1.loan_amount AND L2.loan_nbr <= L1.loan_nbr)) AS rk FROM Loans AS L1 ORDER BY loan_type, rk;
  • 19. SELECT loan_nbr, loan_date, loan_amount, loan_type, ROW_NUMBER() OVER(PARTITION BY loan_type ORDER BY loan_amount DESC, loan_nbr) AS rk FROM Loans ORDER BY loan_type, rk;
  • 20.
  • 21. loan_nbr customer_nbr loan_date loan_amount loan_type 2 2 2008-02-15 00:00:00.000 1000.00 personal 3 1 2008-03-11 00:00:00.000 4500.00 business 4 3 2008-03-12 00:00:00.000 2000.00 personal loan_nbr customer_nbr loan_date loan_amount loan_type 1 1 2008-01-01 00:00:00.000 1500.00 personal 2 2 2008-02-15 00:00:00.000 1000.00 personal 3 1 2008-03-11 00:00:00.000 5000.00 business loan_nbr customer_nbr loan_date loan_amount loan_type 2 2 2008-02-15 00:00:00.000 1000.00 personal 3 1 2008-03-11 00:00:00.000 4500.00 business 4 3 2008-03-12 00:00:00.000 2000.00 personal
  • 22. -- Update changed UPDATE Loans SET loan_amount = (SELECT D.loan_amount FROM DailyChangedLoans AS D WHERE D.loan_nbr = Loans.loan_nbr AND D.loan_amount <> Loans.loan_amount) WHERE EXISTS(SELECT * FROM DailyChangedLoans AS D WHERE D.loan_nbr = Loans.loan_nbr AND D.loan_amount <> Loans.loan_amount); -- Insert new loans INSERT INTO Loans (loan_nbr, customer_nbr, loan_date, loan_amount, loan_type) SELECT loan_nbr, customer_nbr, loan_date, loan_amount, loan_type FROM DailyChangedLoans AS D WHERE NOT EXISTS(SELECT * FROM Loans AS L WHERE D.loan_nbr = L.loan_nbr); -- Remove deleted DELETE FROM Loans WHERE NOT EXISTS(SELECT * FROM DailyChangedLoans AS D WHERE D.loan_nbr = Loans.loan_nbr);
  • 23. -- Using a single MERGE statement MERGE INTO Loans AS L USING DailyChangedLoans AS D ON D.loan_nbr = L.loan_nbr WHEN MATCHED AND L.loan_amount <> D.loan_amount THEN UPDATE SET loan_amount = D.loan_amount WHEN NOT MATCHED THEN INSERT VALUES(D.loan_nbr, D.customer_nbr, D.loan_date, D.loan_amount, D.loan_type) WHEN NOT MATCHED BY SOURCE THEN DELETE;
  • 24.
  • 25.
  • 26. loan_nbr customer_nbr loan_date loan_amount loan_type 1 1 2008-01-01 00:00:00.000 1500.00 personal 2 2 2008-01-02 00:00:00.000 1000.00 personal 3 1 2008-01-03 00:00:00.000 5000.00 business 4 3 2008-01-12 00:00:00.000 2000.00 personal 5 4 2008-01-13 00:00:00.000 1200.00 personal 6 3 2008-01-29 00:00:00.000 4000.00 business 7 5 2008-01-30 00:00:00.000 3500.00 business 8 2 2008-01-31 00:00:00.000 2000.00 personal start_date end_date 2008-01-01 00:00:00.000 2008-01-03 00:00:00.000 2008-01-12 00:00:00.000 2008-01-13 00:00:00.000 2008-01-29 00:00:00.000 2008-01-31 00:00:00.000
  • 27. -- Find last date for date range -- and use as grouping factor SELECT MIN(loan_date) AS start_date, MAX(loan_date) AS end_date FROM (SELECT loan_date, (SELECT MIN(L2.loan_date) FROM Loans AS L2 WHERE L2.loan_date >= L1.loan_date AND NOT EXISTS (SELECT * FROM Loans AS L3 WHERE L3.loan_date = DATEADD(DAY, 1, L2.loan_date)) ) AS base FROM Loans AS L1) AS L GROUP BY base;
  • 28. -- Preparation for solution SELECT loan_date, DATEDIFF(DAY, '19000101', loan_date) AS days_since_base_date, ROW_NUMBER() OVER(ORDER BY loan_date) AS rn FROM Loans; loan_date days_since_base_date rn 2008-01-01 00:00:00.000 39446 1 2008-01-02 00:00:00.000 39447 2 2008-01-03 00:00:00.000 39448 3 2008-01-12 00:00:00.000 39457 4 2008-01-13 00:00:00.000 39458 5 2008-01-29 00:00:00.000 39474 6 2008-01-30 00:00:00.000 39475 7 2008-01-31 00:00:00.000 39476 8
  • 29. -- Solution with ROW_NUMBER SELECT MIN(loan_date) AS start_date, MAX(loan_date) AS end_date FROM (SELECT loan_date, DATEDIFF(DAY, '19000101', loan_date) - ROW_NUMBER() OVER(ORDER BY loan_date) AS base FROM Loans) AS L GROUP BY base;