I am running into an issue with a simple SQL math operation of qty * price is returning an incorrect value.
This is SQL server 2005. Compatibility is set to 80 for 2000 SQL server.
Any help on understanding why I am having the problem shown below
For example:
Transaction Table:
id price qty
1 2.77 20.00
1 2.77 25.00
1 2.77 10.00
2 0.10 50.00
2 0.10 80.00
3 0.10 50.00
3 0.10 60.00
SQL
Select id, price, qty, (qty * price) from transact
The actual problem was this and it was my fault :(
Select id, CAST(price AS DECIMAL(5,2)), qty, (qty * price) from transact
Returns the following:
id price qty Total
1 2.77 20.00 55.400000 Correct
1 2.77 25.00 69.250000 Correct
1 2.77 10.00 27.700000 Correct
2 0.10 50.00 4.800000 Should be 5.0000
2 0.10 80.00 7.680000 Should be 8.0000
2 0.10 50.00 5.050000 Should be 5.0000
2 0.10 60.00 6.060000 Should be 6.0000
3 39.00 1.00 39.000000 Correct
3 39.00 2.00 78.000000 Correct
3 39.00 3.00 117.000000 Correct
You price is being rounded somewhere. The select you are running is not showing the actual price.
select round(0.096, 2) price, 0.096 * 50.00 total
Result:
price total
0.10 4.80000
Related
I have financial data that I want to categorise (using NTILE()) by two columns that contain percentage values (risk, debt_to_assets). My end goal is that I want to aggregate some other column (profit) by the two categories, but that's not related to my issue at hand. The data looks something like this:
profit
risk
debt_to_assets
7000
0.10
0.20
1000
0.40
0.70
3000
0.15
0.50
4000
0.30
0.30
2000
0.20
0.60
The issue I'm trying to solve is that I want the categories to be nested such that, in addition to the population distribution being uniform, the categories of the inner quantile are consistent across the categories of the outer quantile in terms of the range that defines the categories (i.e. I want the min and max value for the inner categories (x0, y0), (x1, y0), (x2, y0), ... to all be the same or as close as possible, where the x's are the outer category and the y's are the inner category).
Ideally if I were to aggregate the columns used for the NTILE() function (using 3 inner categories and 3 outer categories for example) I'd want a table that resembles the following:
risk_cat
dta_cat
min_risk
max_risk
min_dta
max_dta
count
1
1
0.00
0.33
0.00
0.33
100
1
2
0.00
0.33
0.34
0.67
100
1
3
0.00
0.33
0.68
1.00
100
2
1
0.34
0.67
0.00
0.33
100
2
2
0.34
0.67
0.34
0.67
100
2
3
0.34
0.67
0.68
1.00
100
3
1
0.68
1.00
0.00
0.33
100
3
2
0.68
1.00
0.34
0.67
100
3
3
0.68
1.00
0.68
1.00
100
These are the solutions I've tried but they only solve part of the issue, not the whole thing:
SELECT *,
NTILE(3) OVER (
ORDER BY risk
) AS risk_cat,
NTILE(3) OVER (
ORDER BY debt_to_assets
) AS dta_cat
FROM my_table
This would result in an aggregated table like this:
risk_cat
dta_cat
min_risk
max_risk
min_dta
max_dta
count
1
1
0.00
0.33
0.00
0.33
10
1
2
0.00
0.33
0.34
0.67
55
1
3
0.00
0.33
0.68
1.00
180
2
1
0.34
0.67
0.00
0.33
135
2
2
0.34
0.67
0.34
0.67
140
2
3
0.34
0.67
0.68
1.00
100
3
1
0.68
1.00
0.00
0.33
130
3
2
0.68
1.00
0.34
0.67
110
3
3
0.68
1.00
0.68
1.00
40
The problem is that the count across the two categories isn't uniform.
WITH outer_cat AS (
SELECT *,
NTILE(3) OVER (
ORDER BY risk
) AS risk_cat
FROM my_table
)
SELECT *,
NTILE(3) OVER(
PARTITION BY risk_cat
ORDER BY debt_to_assets
) AS dta_cat
FROM outer_cat
The aggregated table for this might resemble the following:
risk_cat
dta_cat
min_risk
max_risk
min_dta
max_dta
count
1
1
0.00
0.33
0.10
0.70
100
1
2
0.00
0.33
0.71
0.90
100
1
3
0.00
0.33
0.91
1.00
100
2
1
0.34
0.67
0.05
0.35
100
2
2
0.34
0.67
0.36
0.60
100
2
3
0.34
0.67
0.61
0.90
100
3
1
0.68
1.00
0.00
0.25
100
3
2
0.68
1.00
0.26
0.50
100
3
3
0.68
1.00
0.51
0.80
100
The problem this time is that the min and max values for the inner category vary to much across the outer category.
SELECT *,
NTILE(9) OVER(
ORDER BY risk, debt_to_assets
) AS dual_cat
FROM my_table
The aggregated table for this looks something like the following:
dual_cat
min_risk
max_risk
min_dta
max_dta
count
1
0.00
0.11
0.55
1.00
100
2
0.12
0.22
0.35
1.00
100
3
0.23
0.33
0.15
1.00
100
4
0.34
0.44
0.40
1.00
100
5
0.45
0.55
0.10
1.00
100
6
0.56
0.66
0.10
0.95
100
7
0.67
0.77
0.05
1.00
100
8
0.78
0.88
0.20
1.00
100
9
0.89
1.00
0.00
1.00
100
This was just a last attempt at a solution after the previous two didn't work. This attempt didn't capture any of the behaviour that I was looking for.
Is there a solution to my problem that I'm not seeing?
I want to ask how to enter NULL in Table 2 with values in LITHOLOGY column.
Thanks
Table 1
LITHOLOGY
SITE_ID
DEPTH_FROM
DEPTH_TO
BXg
DB-01
0.00
4.50
BXg2
DB-01
4.50
10.00
BXg2
DB-02
4.00
10.00
BXg2
DB-02
0.00
4.00
Table 2
SITE_ID
DEPTH_FROM
DEPTH_TO
CORE_RECOV
LITHOLOGY
DB-01
0.00
2.00
0.20
DB-01
2.00
4.00
0.30
DB-01
4.00
6.00
0.22
DB-01
6.00
8.00
0.32
DB-01
8.00
10.00
0.42
DB-02
0.00
3.00
0.12
DB-02
3.00
5.00
0.42
DB-02
5.00
10.00
0.92
As per your question, the below will put NULL in every LITHOLOGY column where LITHOLOGY is not null.
If you want to replace blank fields with null use WHERE LITHOLOGY = '' instead
UPDATE Table2
SET LITHOLOGY = NULL
WHERE LITHOLOGY IS NOT NULL;
The query is used to get balance of certain client
SELECT t.[InvoiceID], t.S_Type as Type,
t.Date, t.Debit, t.Credit, b.Balance
FROM Statement as t CROSS apply
(SELECT Balance = SUM(Debit) - SUM(Credit)
FROM Statement as x
WHERE (x.date < t.date or
x.date = t.date
) AND
x.InvoiceID = t.InvoiceID
AND x.CustID = t.CustID
) b
WHERE t.CustID ='2' and date between '2015-01-01' and '2016-01-12'
order by InvoiceID, Type desc, Date
out out i get
InvoiceID Type Date Debit Credit Balance
4 Sales Invoice 2015-06-09 520.00 0.00 520.00
4 Receipt Voucher 2016-01-04 0.00 520.00 0.00
6 Sales Invoice 2015-06-09 160.00 0.00 160.00
6 Receipt Voucher 2016-01-04 0.00 160.00 0.00
9 Sales Invoice 2015-06-09 850.00 0.00 850.00
9 Receipt Voucher 2016-01-04 0.00 850.00 0.00
13 Sales Invoice 2015-06-09 200.00 0.00 200.00
20 Sales Invoice 2015-07-11 1225.00 0.00 1225.00
176 Sales Invoice 2015-12-14 900.00 0.00 900.00
the issue is with with sales invoices # 13 20 176 its supposed to sum the debit of invoice and show in balance
so right out put should be like this
InvoiceID Type Date Debit Credit Balance
4 Sales Invoice 2015-06-09 520.00 0.00 520.00
4 Receipt Voucher 2016-01-04 0.00 520.00 0.00
6 Sales Invoice 2015-06-09 160.00 0.00 160.00
6 Receipt Voucher 2016-01-04 0.00 160.00 0.00
9 Sales Invoice 2015-06-09 850.00 0.00 850.00
9 Receipt Voucher 2016-01-04 0.00 850.00 0.00
13 Sales Invoice 2015-06-09 200.00 0.00 200.00
20 Sales Invoice 2015-07-11 1225.00 0.00 1425.00
176 Sales Invoice 2015-12-14 900.00 0.00 2325.00
I think the logic is slightly off in the subquery.
SELECT t.[InvoiceID], t.S_Type as Type,
t.Date, t.Debit, t.Credit, b.Balance
FROM Statement as t CROSS apply
(SELECT Balance = SUM(Debit) - SUM(Credit)
FROM Statement as x
WHERE x.CustID = t.CustID AND
(x.date < t.date or
x.date = t.date AND x.InvoiceID <= t.InvoiceID
)
) b
WHERE t.CustID ='2' and
date between '2015-01-01' and '2016-01-12'
ORDER BY InvoiceID, Type desc, Date;
In other words, the prioritization for the cumulative sum should be date first and then when the dates are the same, use the invoice.
This means that all your values are really being miscalculated, because each invoice is starting over (with your original logic). However, the earlier invoices are fully paid, so you don't see the issue with them.
Note: in more recent versions of SQL Server, this is much easier (and more efficient) with the cumulative sum syntax:
sum(debit - credit) over (partition by custid order by date, invoiceid)
Or, if debit and credit could take on NULL values:
sum(coalesce(debit, 0) - coalesce(credit, 0)) over (partition by custid order by date, invoiceid)
Given that I have the following dataset in TempTable:
Item Item Desc Location Qty LeasedQty
----------------------------------------------------------------
IT2250 1/2CANTOP NYC 1.00 30.00
IT5550 FCM 2K NYC 6.00 8.00
IT2075 HPTL 750 LA 4.00 44.00
IT12506 DOUBLE DOOR 10" CALI 60.00 0.00
IT3606 BAG180 CALI 25.00 0.00
IT3606 BAG180 NYC 20.00 40.00
IT3606 BAG180 LA 5.00 45.00
IT50 2K NYC 6.00 8.00
IT50 2K LA 4.00 44.00
IT50 2K CALI 60.00 0.00
How can I partition this data so that It will be Like the following:
Item Item Desc Location Qty LeasedQty RNK
----------------------------------------------------------------------
IT2250 1/2CANTOP NYC 1.00 30.00 1
IT5550 FCM 2K NYC 6.00 8.00 2
IT2075 HPTL 750 LA 4.00 44.00 3
IT12506 DOUBLE DOOR 10" CALI 60.00 0.00 4
IT3606 BAG180 CALI 25.00 0.00 5
IT3606 BAG180 NYC 20.00 40.00 5
IT3606 BAG180 LA 5.00 45.00 5
IT50 2K NYC 6.00 8.00 6
IT50 2K LA 4.00 44.00 6
IT50 2K CALI 60.00 0.00 6
Basically, I want the data to group by each item and gather the TOP 20 items based on the QTY (DESCENDING)
To get that rank this will help you
SELECT Dense_rank()
OVER (
ORDER BY Item) rnk,
*
FROM TempTable
Added to get top 20 records
SELECT TOP 20 *
FROM (SELECT Dense_rank()
OVER (
ORDER BY Item,qty desc) rnk,
*
FROM TempTable) a
WHERE rnk <= 20
I have a following situation
table1
PricelistID ValidTo Currency Markup
1 2013-12-31 USD 1.2
2 2013-12-31 USD 1.25
3 2013-12-31 USD 1.3
4 2013-12-31 USD 1.1
table2
PricelistID PeriodID Price
1 1 10.00
1 2 20.00
2 3 15.00
3 4 50.00
4 5 30.00
Now I have a situation where I need to add new pricelist with values(2013-12-31, USD, 1.5) (only in in table 1) that would inherit values of pricelistID 4 in table 2, how can I do it?
Query should return
PricelistiD ValidTo Currency Markup PeriodID Price
5 2013-12-31 USD 1.5 5 30.00