views:

82

answers:

2

here is my current queries:

1

SELECT FilteredInvoice.accountidname, 
       FilteredInvoice.createdon, 
       FilteredInvoice.createdon AS sort_date, 
       FilteredInvoice.duedate, 
       FilteredInvoice.invoicenumber, 
       FilteredInvoice.statecodename, 
       FilteredInvoice.totalamount_base, 
       CONVERT(datetime, NULL) AS mag_paymentdate, 
       0 AS mag_amount_base, 
       GETDATE() AS Today
  FROM FilteredAccount AS CRMAF_FilteredAccount 
  JOIN FilteredInvoice ON FilteredInvoice.accountid = CRMAF_FilteredAccount.accountid 
  JOIN FilteredMag_Payment ON FilteredInvoice.invoiceid = FilteredMag_Payment.mag_invoiceid
 WHERE (FilteredInvoice.statecodename <> 'Canceled')

2

   SELECT FilteredInvoice_1.accountidname, 
          FilteredInvoice_1.createdon, 
          FilteredInvoice_1.createdon AS sort_date, 
          FilteredInvoice_1.duedate, 
          FilteredInvoice_1.invoicenumber, 
          FilteredInvoice_1.statecodename, 
          FilteredInvoice_1.totalamount_base, 
          FilteredMag_Payment.mag_paymentdate, 
          FilteredMag_Payment.mag_amount_base, 
          GETDATE() AS Today
     FROM FilteredAccount AS CRMAF_FilteredAccount 
LEFT JOIN FilteredInvoice AS FilteredInvoice_1 ON FilteredInvoice_1.accountid = CRMAF_FilteredAccount.accountid 
     JOIN FilteredMag_Payment ON FilteredInvoice_1.invoiceid = FilteredMag_Payment.mag_invoiceid
    WHERE (FilteredInvoice_1.statecodename <> 'Canceled')

These alone do exactly what i am wanting them to but as soon as i try and join them using a "UNION" or "Sub-query" the second query always breaks and displays the wrong information.

Am I just being blond not being able to work this out or am I actually doing something wrong.

All help is appreciated.

Many thanks Simon.

EDIT: What I mean by "Wrong information" is that the 2nd query is returning all values rather then following the CRMAF_ prefix and returning only values from the account it is run on.

+2  A: 

It's hard to guess what do you mean by "wrong information" but I believe you want UNION ALL rather than UNION.

UNION removes duplicates so the records from the second query won't be returned if they were previously returned by the first query. In addition, the possible duplicates within one query will be eliminated too.

The number of records in a UNION can be less than the total count of records in two queries.

If you just want to concatenate two recordsets, use UNION ALL:

SELECT FilteredInvoice.accountidname, 
       FilteredInvoice.createdon, 
       FilteredInvoice.createdon AS sort_date, 
       FilteredInvoice.duedate, 
       FilteredInvoice.invoicenumber, 
       FilteredInvoice.statecodename, 
       FilteredInvoice.totalamount_base, 
       CONVERT(datetime, NULL) AS mag_paymentdate, 
       0 AS mag_amount_base, 
       GETDATE() AS Today
  FROM FilteredAccount AS CRMAF_FilteredAccount 
  JOIN FilteredInvoice ON FilteredInvoice.accountid = CRMAF_FilteredAccount.accountid 
  JOIN FilteredMag_Payment ON FilteredInvoice.invoiceid = FilteredMag_Payment.mag_invoiceid
 WHERE (FilteredInvoice.statecodename <> 'Canceled')
UNION ALL
   SELECT FilteredInvoice_1.accountidname, 
          FilteredInvoice_1.createdon, 
          FilteredInvoice_1.createdon AS sort_date, 
          FilteredInvoice_1.duedate, 
          FilteredInvoice_1.invoicenumber, 
          FilteredInvoice_1.statecodename, 
          FilteredInvoice_1.totalamount_base, 
          FilteredMag_Payment.mag_paymentdate, 
          FilteredMag_Payment.mag_amount_base, 
          GETDATE() AS Today
     FROM FilteredAccount AS CRMAF_FilteredAccount 
LEFT JOIN FilteredInvoice AS FilteredInvoice_1 ON FilteredInvoice_1.accountid = CRMAF_FilteredAccount.accountid 
     JOIN FilteredMag_Payment ON FilteredInvoice_1.invoiceid = FilteredMag_Payment.mag_invoiceid
    WHERE (FilteredInvoice_1.statecodename <> 'Canceled')
Quassnoi
+1 as I was about to guess the same; the *reason* this is probably the case is UNION's characteristic elimination of duplicate rows where UNION ALL takes things exactly as they are. btw - take OMG's advice in the comment; the real answer is to not use a UNION at all...
Tahbaza
@Tahbaza: in @op's current query, `LEFT JOIN` can be replaced with `INNER JOIN` and will yield the same result. See my comment to the question.
Quassnoi
At one stage I had tried this but it still returns the same as the normal "UNION" so this is not the fix I am after.
Simon
@Simon: it would probably help if you told us what is it you're after. What do you get and what do you expect to get?
Quassnoi
+1  A: 

It looks to me as though you should be able to get the same results as you would from the UNIONed query, with the following:

   SELECT FilteredInvoice_1.accountidname, 
          FilteredInvoice_1.createdon, 
          FilteredInvoice_1.createdon AS sort_date, 
          FilteredInvoice_1.duedate, 
          FilteredInvoice_1.invoicenumber, 
          FilteredInvoice_1.statecodename, 
          FilteredInvoice_1.totalamount_base, 
          CASE PF.pay_flag 
              WHEN 0.0 THEN CONVERT(datetime, NULL)
              ELSE FilteredMag_Payment.mag_paymentdate
          END AS mag_paymentdate, 
          FilteredMag_Payment.mag_amount_base * PF.pay_flag AS mag_amount_base, 
          GETDATE() AS Today
     FROM FilteredAccount AS CRMAF_FilteredAccount 
     CROSS JOIN (SELECT 1.0 pay_flag UNION SELECT 0.0) AS PF
     JOIN FilteredInvoice AS FilteredInvoice_1 ON FilteredInvoice_1.accountid = CRMAF_FilteredAccount.accountid 
     LEFT JOIN FilteredMag_Payment ON FilteredInvoice_1.invoiceid = FilteredMag_Payment.mag_invoiceid
    WHERE (FilteredInvoice_1.statecodename <> 'Canceled') AND
          (PF.pay_flag = 0 OR FilteredMag_Payment.mag_invoiceid IS NOT NULL)

EDIT: LEFT JOIN FilteredMag_Payment

FURTHER EDIT: added final parenthesised OR condition to WHERE clause.

Mark Bannister
@ Mark: this is just what I am after it just needs a few tweaks, it isn't showing invoices that don't have payments for them. is this an easy fix or more complex? all help is greatly appreciated.
Simon
@Simon: I have changed the join to the FilteredMag_Payment table to a LEFT JOIN - this should bring back Invoices with no payments on them.
Mark Bannister
@Mark: That is brilliant exactly what I want except it is showing invoices twice that haven't got a payment associated to them.
Simon
@Simon: I have added a final condition to the WHERE clause that should resolve this - try now.
Mark Bannister
@Mark: you are a legend I have been trying to do this for months thanks so much for your help.
Simon