Link to home
Start Free TrialLog in
Avatar of Chris Michalczuk
Chris MichalczukFlag for United Kingdom of Great Britain and Northern Ireland

asked on

How do I Convert float to money or decimal in sql query?

How do I convert the 2 fields in this to money or decimal 2 . The results are not right as I think this is because both fields are FLOAT.
How do I convert them in the query to say MONEY or DECIMAL as 2 decimal places?

Select I.Invoice_Number, I.Items_Net, Sum(II.Net_Amount) Value,i.INVOICE_TYPE
From Invoice I
  Inner Join Invoice_Item II on I.Invoice_Number = II.Invoice_Number
 
Group By I.Invoice_Number, I.Items_Net,i.INVOICE_TYPE
having Sum(II.Net_Amount)<>I.Items_Net
Order By I.Invoice_Number
Avatar of Brian Crowe
Brian Crowe
Flag of United States of America image

Select I.Invoice_Number, I.Items_Net, CAST(Sum(II.Net_Amount) AS DECIMAL(9,2))
   CAST(Value AS DECIMAL(9,2), i.INVOICE_TYPE
From Invoice I
Inner Join Invoice_Item II on I.Invoice_Number = II.Invoice_Number
Group By I.Invoice_Number, I.Items_Net,i.INVOICE_TYPE
having Sum(II.Net_Amount)<>I.Items_Net
Order By I.Invoice_Number
REAL is an "approximate numeric" so comparison (not equal) will be fraught with difficulty. Money & decimal are "exact numerics" suited to comparison:

But you have a decision to make.
Do you want to sum the real values -- then convert
or
Do you want to convert first -- then sum

This converts first then sums, and it is using MONEY.
SELECT
      I.Invoice_Number
    , i.INVOICE_TYPE
    , CONVERT(MONEY, I.Items_Net) AS Items_Net
    , SUM(CONVERT(MONEY, II.Net_Amount)) AS Value
FROM Invoice I
      INNER JOIN Invoice_Item II ON I.Invoice_Number = II.Invoice_Number
GROUP BY
      I.Invoice_Number
    , i.INVOICE_TYPE
    , CONVERT(MONEY, I.Items_Net)
HAVING SUM(CONVERT(MONEY, II.Net_Amount)) <> CONVERT(money, I.Items_Net)
ORDER BY
      I.Invoice_Number

Open in new window

You can substitute "DECIMAL(12,4)" or similar where you see "MONEY"

The alternative is:
SELECT
      I.Invoice_Number
    , i.INVOICE_TYPE
    , CONVERT(MONEY, I.Items_Net) AS Items_Net
    , CONVERT(MONEY, SUM(II.Net_Amount)) AS Value
FROM Invoice I
      INNER JOIN Invoice_Item II ON I.Invoice_Number = II.Invoice_Number
GROUP BY
      I.Invoice_Number
    , i.INVOICE_TYPE
    , CONVERT(MONEY, I.Items_Net)
HAVING CONVERT(MONEY, SUM(II.Net_Amount)) <> CONVERT(MONEY, I.Items_Net)
ORDER BY
      I.Invoice_Number

Open in new window

Not sure why you have monetary data in real columns, it isn't a god idea.
Avatar of Chris Michalczuk

ASKER

NEAR THERE THANKS BUT HOW DO i TURN VALUE COLUMN FOR CREDITNOTES TO SHOW A NEGATIVE
THIS CASE STATEMENT DOESNT WORK (SEE ATTACHED FILE FOR RESULTS)

SELECT
      I.Invoice_Number
    , i.INVOICE_TYPE
    , CONVERT(MONEY, I.Items_Net) AS Items_Net
    , SUM(CONVERT(MONEY, II.Net_Amount)) AS Value
FROM Invoice I
      INNER JOIN Invoice_Item II ON I.Invoice_Number = II.Invoice_Number
GROUP BY
      I.Invoice_Number
    , i.INVOICE_TYPE
    , CONVERT(MONEY, I.Items_Net)
----HAVING SUM(CONVERT(MONEY, II.Net_Amount)) <> ABS(CONVERT(money, I.Items_Net))

having SUM(CONVERT(MONEY,II.Net_Amount)) <> CASE WHEN I.Invoice_TYPE = 'Product Credit Note' THEN -1 ELSE 1 END * CONVERT(money, I.Items_Net)

ORDER BY
      I.Invoice_Number
INVOICESDIFFERENCES.xlsx
Try these:
SELECT
      I.Invoice_Number
    , i.INVOICE_TYPE
    , CASE WHEN I.Invoice_TYPE = 'Product Credit Note' THEN -1.0 * CONVERT(MONEY, I.Items_Net) 
           ELSE CONVERT(MONEY, I.Items_Net) 
      END 
      AS Items_Net
    , SUM(CONVERT(MONEY, II.Net_Amount)) AS Value
FROM Invoice I
      INNER JOIN Invoice_Item II ON I.Invoice_Number = II.Invoice_Number
GROUP BY
      I.Invoice_Number
    , i.INVOICE_TYPE
    , CASE WHEN I.Invoice_TYPE = 'Product Credit Note' THEN -1.0 * CONVERT(MONEY, I.Items_Net) 
           ELSE CONVERT(MONEY, I.Items_Net) 
      END 
HAVING SUM(CONVERT(MONEY,II.Net_Amount)) <>  CASE WHEN I.Invoice_TYPE = 'Product Credit Note' THEN -1.0 * CONVERT(MONEY, I.Items_Net) ELSE CONVERT(MONEY, I.Items_Net) END
;

Open in new window

SELECT
      I.Invoice_Number
    , i.INVOICE_TYPE
    , Items_Net
    , Value
FROM (
      SELECT
            I.Invoice_Number
          , i.INVOICE_TYPE
          , CASE WHEN I.Invoice_TYPE = 'Product Credit Note' THEN -1.0 * CONVERT(MONEY, I.Items_Net) 
                 ELSE CONVERT(MONEY, I.Items_Net) 
            END 
            AS Items_Net
          , SUM(CONVERT(MONEY, II.Net_Amount)) AS Value
      FROM Invoice I
            INNER JOIN Invoice_Item II ON I.Invoice_Number = II.Invoice_Number
      GROUP BY
            I.Invoice_Number
          , i.INVOICE_TYPE
          , CASE WHEN I.Invoice_TYPE = 'Product Credit Note' THEN -1.0 * CONVERT(MONEY, I.Items_Net) 
                 ELSE CONVERT(MONEY, I.Items_Net) 
            END 
      ) AS d
WHERE Value <> Items_Net
;

Open in new window

nb: I probably will not be online while you read this.
1st one works but doesnt covert the credit note as minuses
the 2nd one errors

Msg 4104, Level 16, State 1, Line 2
The multi-part identifier "I.Invoice_Number" could not be bound.
Msg 4104, Level 16, State 1, Line 3
The multi-part identifier "i.INVOICE_TYPE" could not be bound.
In lines 2 and 3 remove the aliases.

That second a query is the same as the first so if it isnt eorking plesse provide a small sample of data from each table
ASKER CERTIFIED SOLUTION
Avatar of PortletPaul
PortletPaul
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
this works in your example but when I apply it to my data Product Credit Notes are still coming out as positive numbers not negatives which is what I wanted. Must be my data somehow but it isn't applying the CASE WHEN I.Invoice_TYPE = 'Product Credit Note' THEN -1.0  to my dataset for some reason
If the case expression isn't wrking then perhaps the string isn't exactly correct, maybe:

CASE WHEN I.Invoice_TYPE LIKE 'Product Credit Note%' THEN -1.0

you may just need to fiddle with that case expression