Domanda

Your boss loved the pivot query you wrote in the first project. He showed the accountant, and she said she wants to see a similar query, but with sales in the last 30, 60, and 90 days.

MySQL has a function that can be used to compare two dates - DATEDIFF: SELECT DATEDIFF(now(), DateOfPurchase) FROM Purchases MySQL subtracts the DateOfPurchase from "now" and returns an integer representing the number of days between those two dates.

You can use this function to write your accountant's requested pivot query. The results might look similar to the following:

 Album         D30  D60  D90

 OK Computer    2    5    3 
 Sea Change     8    6    2 

Note that each time period has separate data. D60 data should be for purchases from 31 to 60 days ago, not everything purchased in the last 60 days. Similarly, D90 data should be for purchases from 61 to 90 days ago, not everything purchased in the last 90 days.

Do not create a separate table or a view.

Save your query as dba1lesson10project2.sql and then hand in the project.

I have entered Purchase data into my Purchases table that are 30 60 and 90 days apart.

My table looks like

 Customer ID     DateOfPurchase     SongID

     1              2007-03-31        3
     3              2007-06-30        4
     4              2007-09-30        4
     5              2007-12-31        5
     2              2013-08-21        2
     4              2013-07-22        5
     5              2013-06-22        1

So, I'm only going to have 1 purchase per 30 day period to show. My previous project was to show purchases per quarter, which is why the 2007 data is in there. I've been speaking with my instructor regarding this, and he said my code for this would be similar to my code for my last project.

I have tried

 SELECT DATEDIFF(now(), DateOfPurchase),
 SUM(CASE WHEN DateOfPurchase <= 30 THEN 1 ELSE 0 END) AS 'D30',
 SUM(CASE WHEN DateOfPurchase >= 31 AND DateOfPurchase = 60 THEN 1 ELSE 0 END) AS 'D60',
 SUM(CASE WHEN DateOfPurchase >= 61 AND DateOfPurchase = 90 THEN 1 ELSE 0 END) AS 'D90'
 FROM Purchases;

Which returns:

 DATEDIFF(now(), DateOfPurchase   D30   D60   D90

              2365                 0     0     0

I have tried a couple different variants of this code, which pretty much return the same result. Other than the number in the first column being the same.

The code to my last project is below, if that helps at all.

 SELECT A.Title,
 SUM(CASE WHEN QUARTER(DateOfPurchase) = 1 THEN 1 ELSE 0 END) AS 'Q1',
 SUM(CASE WHEN QUARTER(DateOfPurchase) = 2 THEN 1 ELSE 0 END) AS 'Q2',
 SUM(CASE WHEN QUARTER(DateOfPurchase) = 3 THEN 1 ELSE 0 END) AS 'Q3',
 SUM(CASE WHEN QUARTER(DateOfPurchase) = 4 THEN 1 ELSE 0 END) AS 'Q4'
 FROM Albums AS A
 INNER JOIN Songs AS S
 ON A.AlbumID = S.AlbumID
 INNER JOIN Purchases as P
 ON S.SongID = P.SongID
 GROUP BY A.Title;

I'm also aware I will have to do the table joins for this project also. I'm just trying to get the correct output for D30 D60 and D90 before I do that.

È stato utile?

Soluzione

You want something like this

SELECT SUM(CASE WHEN DATEDIFF(CURDATE(), DateOfPurchase) 
                     BETWEEN  0 AND 30 THEN 1 ELSE 0 END) D30,
       SUM(CASE WHEN DATEDIFF(CURDATE(), DateOfPurchase) 
                     BETWEEN 31 AND 60 THEN 1 ELSE 0 END) D60,
       SUM(CASE WHEN DATEDIFF(CURDATE(), DateOfPurchase) 
                     BETWEEN 61 AND 90 THEN 1 ELSE 0 END) D90
  FROM Purchase
 WHERE DateOfPurchase BETWEEN CURDATE() - INTERVAL 90 DAY AND CURDATE()

Note: Since you're pivoting only 90 days worth of data from current day you better filter out everything else with WHERE clause and do it in an index-friendly manner.

Sample output:

| D30 | D60 | D90 |
|-----|-----|-----|
|   1 |   1 |   1 |

Here is SQLFiddle demo

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top