Passing values into CTE in single query?

时间:2016-04-04 17:31:19

标签: sql

I have a query with a CTE. The CTE pulls data from a couple tables within a specified date range. What I want to do is to select from the CTE once, with one data range, then join that to a second call to the CTE, this time with a second date range. My problem is that I can't figure out how to pass the dates to the CTE. I'm using Pyodbc, talking to an iSeries OS400 machine. I can't use variables or multiple statements like I could in an MSSQL database, which is the only solution I've been able to find thus far.

My current attempt looks like this:

WITH salesQuery AS (  
  SELECT
    items.imvnno AS itemNumber,
    sum(historyTable.obqtsh) AS quantityShipped,
    sum(historyTable.obaslp) AS sales,
    obivdt AS actualDate,
    obivdt AS startDate,
    obivdt AS endDate  
  FROM aplus60fad.hsde3 historyTable  
    INNER JOIN aplus60fad.itmst items ON obitno = imitno  
  WHERE obcono = 1
    AND obcsno = '[ID]'
    AND actualDate BETWEEN startDate AND endDate  
  GROUP BY imvnno  
)  
SELECT
  salesQuery_2014.itemNumber as itemNumber_2014,
  salesQuery_2014.quantityShipped as quantityShipped_2014,
  salesQuery_2014.sales as sales_2014,
  salesQuery_2015.itemNumber as itemNumber_2015,
  salesQuery_2015.quantityShipped as quantityShipped_2015,
  salesQuery_2015.sales as sales_2015
FROM salesQuery salesQuery_2014  
  JOIN salesQuery salesQuery_2015 on salesQuery_2014.itemNumber = salesQuery_2015.itemNumber
WHERE salesQuery_2014.startDate = '111201'
  AND salesQuery_2014.endDate = '141231'
  AND salesQuery_2015.startDate = '141201'
  AND salesQuery_2015.endDate = '150404';

I'm getting an error that "ACTUALDATE" is not found in specified tables. I'm not sure what's going on, though, because "actualDate" (the error puts it in all caps, I don't) is a column identifier I specify right in the CTE. I want to pass two date ranges, as you can see from the query below the CTE, but I don't know how to do that. Again, it's an IBM iSeries through Pyodbc. Thanks in advance.

2 个答案:

答案 0 :(得分:1)

The reason for the error is that in your CTE you are using "actualDate" in the WHERE clause.

You cannot do this in the CTE, because "actualDate" is an alias that you created in the CTE. You have to use the real column name (obivdt) in the CTE's WHERE clause.

EDIT:

On further look at what you appear to be trying to do, the way to do this is with two CTE's. You cannot pass values "upward" from an outer query to a CTE. There is NO WAY for a CTE to be aware of the values you are using in the WHERE clause of your outer query.

The way to do what you want is like this, in psuedocode:

WITH cte2014 AS (
  CTE Query for Dates in 2014
),
cte2015 AS (
  CTE Query for Dates in 2015
)
SELECT ...
FROM cte2014 JOIN cte2015 on {Key Column}

答案 1 :(得分:0)

Thanks to the comments and answer, I got a valid query. I say 'valid' because, syntactically, it's fine--no errors and it runs. Functionally, I'm not so sure, but at least it doesn't error out. In case anyone is looking for what the right way is:

WITH salesQuery AS (  
  SELECT items.IMVNNO AS itemNumber, sum(historyTable.OBQTSH) as quantityShipped, sum(historyTable.OBASLP) AS sales,
  historyTable.obivdt as salesDate  
  FROM APLUS60FAD.hsde3 historyTable  
  inner join APLUS60FAD.ITMST items  
  on OBITNO = IMITNO  
  WHERE OBCONO = 1 and OBCSNO = '[ID]'  
  GROUP BY imvnno, obivdt 
 )  
 select salesQuery_2014.itemNumber as itemNumber_2014,   salesQuery_2014.quantityShipped as quantityShipped_2014,       salesQuery_2014.sales as sales_2014,
  salesQuery_2015.itemNumber as itemNumber_2015,   salesQuery_2015.quantityShipped as quantityShipped_2015,       salesQuery_2015.sales as sales_2015
 FROM (  
   SELECT *  
   from salesQuery  
   WHERE salesDate between '111201' and '131231'  
  ) salesQuery_2014  
 JOIN (  
   SELECT *  
   from salesQuery  
   WHERE salesDate between '131201' and '150404'  
  ) salesQuery_2015  
 on salesQuery_2014.itemNumber = salesQuery_2015.itemNumber