I have tried to run a query I phpmyAdmin as follows
SELECT
orders_history.id,
orders_history.`items`,
orders_history.`transaction_id`,
orders_history.`quantity`,
estockClaims.`esquantity`,
IFNULL( esquantity, 0 ),
orders_history.`quantity` - estockClaims.`esquantity` AS myquantity
FROM orders_history
LEFT JOIN estockClaims
ON orders_history.transaction_id = estockClaims.transaction_id
AND orders_history.items = estockClaims.items
LIMIT 0 , 100
And it gives me this result:
----------------------------------------------------------------------
id items transaction_id quantity esquantity IFNULL(esquantity , 0 ) myquantity
1 FR 001 100 NULL 0 NULL
2 BR 002 10 NULL 0 NULL
3 WR 003 25 25 25 0
4 CR 004 50 3 3 47
How to solve this so that NULL is not NULL anyomre but change to 0. Thanks in advance.
Thanks
You already have it in the next column. What you need to do is to drop the original esquantity column and make an alias for the IFNULL... column, like this:
SELECT orders_history.id, orders_history.`items` , orders_history.`transaction_id` ,
orders_history.`quantity` , IFNULL( esquantity, 0 ) AS esquantity,
orders_history.`quantity` - estockClaims.`esquantity` AS myquantity
FROM orders_history
LEFT JOIN estockClaims ON orders_history.transaction_id = estockClaims.transaction_id
AND orders_history.items = estockClaims.items
LIMIT 0 , 100
The change I mentioned is in the line 2 above.
UPDATE
To get
orders_history.`quantity` - estockClaims.`esquantity` AS myquantity
to show expected results, you need to "unnullify" the esquantity field again so that the subtraction would work:
orders_history.`quantity` - IFNULL( estockClaims.`esquantity`, 0 ) AS myquantity
That would ensure you no longer get, for example:
100 - NULL
but this instead:
100 - 0
which will return a proper value.
You can also skip the whole subtraction thing if esquantity is NULL and simply use the value of quantity.
you can use IF to check the esquantity and myquantity columns:
IF(esquantity IS NULL, 0, esquantity)
and
IF(myquantityIS NULL, 0, myquantity)
or use IFNULL as DanFromGermany said
Reason is you are using it as select instead of when doing subtraction. Use it as below:
SELECT orders_history.id, orders_history.`items` , orders_history.`transaction_id` , orders_history.`quantity` , orders_history.`quantity` - IFNULL( esquantity, 0 ) AS myquantity
FROM orders_history
LEFT JOIN estockClaims ON orders_history.transaction_id = estockClaims.transaction_id
AND orders_history.items = estockClaims.items
LIMIT 0 , 100
select temp.id, items, transaction_id, quantity, ifNULL(esquantity, 0), ifNULL(myquantity, 0)
from (SELECT
orders_history.id,
orders_history.`items`,
orders_history.`transaction_id`,
orders_history.`quantity`,
estockClaims.`esquantity`
orders_history.`quantity` - estockClaims.`esquantity` AS myquantity
FROM orders_history
LEFT JOIN estockClaims
ON orders_history.transaction_id = estockClaims.transaction_id
AND orders_history.items = estockClaims.items
LIMIT 0 , 100) temp
You can also use COALESCE to replace the NULL value to 0
check this query.
SELECT orders_history.id, orders_history.`items` , orders_history.`transaction_id` ,
orders_history.`quantity` , COALESCE( esquantity, 0 ) AS esquantity,
orders_history.`quantity` - COALESCE(estockClaims.`esquantity`, 0) AS myquantity
FROM orders_history
LEFT JOIN estockClaims ON orders_history.transaction_id = estockClaims.transaction_id
AND orders_history.items = estockClaims.items
LIMIT 0 , 100
Related
Can anyone point me in the right direction with this query please?
Whichever way i try i continue to get errors
SELECT b.SOLD_TO
, b.CUSTOMER
, b.JANUARY_BUDGET
, Round(sum(d.TOTAL_WEIGHT)/1000,2) AS MONTHLY_DESPATCH
, if(sum(d.TOTAL_WEIGHT)/1000=0 AND b.JANUARY_BUDGET=0,"DOUBLE_ZERO",
if(sum(d.TOTAL_WEIGHT)/1000>0 AND b.JANUARY_BUDGET=0,"NO_BUDGET_GOOD_SHIPMENT",
if(sum(d.TOTAL_WEIGHT)/1000>0 AND b.JANUARY_BUDGET>0 AND (sum(d.TOTAL_WEIGHT)/1000> b.JANUARY_BUDGET,"ABOVE_BUDGET",
if(sum(d.TOTAL_WEIGHT)/1000>0 AND b.JANUARY_BUDGET>0 AND (sum(d.TOTAL_WEIGHT)/1000< b.JANUARY_BUDGET,"POOR_RESULT")))) AS PERFORMANCE
FROM budget2021 b
left JOIN despatches2021 d on d.SOLD_TO = b.SOLD_TO
WHERE b.SOLD_TO=69946 AND d.INVOICE_DATE BETWEEN 20210101 and 20210131
GROUP BY b.SOLD_TO
, b.CUSTOMER
, b.JANUARY_BUDGET
Hm, to diffult to explain, what you made wron a
An IF( condition,true,false) is the form independent of how many you nested.
A godd code indentation helps to handle such things
I also had to add a NULL at the end of the last IF as i don't knpw really where you want to go with this
SELECT
b.SOLD_TO,
b.CUSTOMER,
b.JANUARY_BUDGET,
ROUND(SUM(d.TOTAL_WEIGHT) / 1000, 2) AS MONTHLY_DESPATCH,
IF(SUM(d.TOTAL_WEIGHT) / 1000 = 0
AND b.JANUARY_BUDGET = 0,
'DOUBLE_ZERO',
IF(SUM(d.TOTAL_WEIGHT) / 1000 > 0
AND b.JANUARY_BUDGET = 0,
'NO_BUDGET_GOOD_SHIPMENT',
IF(SUM(d.TOTAL_WEIGHT) / 1000 > 0
AND b.JANUARY_BUDGET > 0
AND (SUM(d.TOTAL_WEIGHT) / 1000 > b.JANUARY_BUDGET),
'ABOVE_BUDGET',
IF(SUM(d.TOTAL_WEIGHT) / 1000 > 0
AND b.JANUARY_BUDGET > 0
AND (SUM(d.TOTAL_WEIGHT) / 1000 < b.JANUARY_BUDGET),
'POOR_RESULT',
NULL)))) AS PERFORMANCE -- here i added the NULL
FROM
budget2021 b
LEFT JOIN
despatches2021 d ON d.SOLD_TO = b.SOLD_TO
WHERE
b.SOLD_TO = 69946
AND d.INVOICE_DATE BETWEEN 20210101 AND 20210131
GROUP BY b.SOLD_TO , b.CUSTOMER , b.JANUARY_BUDGET
I tried finding the answer, but maybe I am too new to MSSQL, I come from MySQL, so this is my question super simplified to go straight to the point:
Imagine we have a table "Things"
Thingie | Value
--------+-------
Thing1 | 10
Thing1 | 15
Thing1 | 16
In MySQL I could do something like this in a query:
SET #halfvalue := 0;
SELECT Thingie, Value,
(#halfvalue := Value / 2) AS HalfValue,
(#halfvalue / 2) AS HalfOfHalf
FROM Things
Which would return
Thingie | Value | HalfValue | HalfofHalf
--------+-------+-----------+------------
Thing1 | 10 | 5.00 | 2.50
Thing1 | 15 | 7.50 | 3.75
Thing1 | 16 | 8.00 | 4.00
Looks pretty simple, the actual one is a tad more complicated.
My problem is, in MSSQL I can't assign, and use a variable on the same SELECT. And I can't find anything similar to this functionality on this simple level.
Any solutions?
Edit, this is the select that contains all those nasty operations:
SELECT
fvh.DocEntry,
MAX( fvs.SeriesName ) AS "Serie",
MAX( fvh.DocNum - 1000000 ) AS "Número",
MAX( fvh.DocDate ) AS "Fecha",
MAX( fvh.U_FacNit ) AS "NIT",
MAX( fvh.U_FacNom ) AS "Nombre",
MAX( IIF( ISNULL( fvh.Address, '' ) = '', fvh.Address2, fvh.Address ) ) AS "Dirección",
SUM( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) AS "Total",
IIF( MAX( fvh.CANCELED ) = 'Y' OR ( SUM( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) = 0 ),
'Anulada',
IIF( SUM( fvd.GTotal ) > SUM( ISNULL( ncd.GTotal, 0 ) ) AND ( SUM( ISNULL( ncd.GTotal, 0 ) ) > 0 ),
'Devuelta',
'Emitida' )
) AS "Estado",
ROUND( ( ( SUM( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) / 1.12 ) * 0.12 ), 4 ) AS "IVA",
ROUND( SUM( IIF( fvd.U_TipoA = 'BB',
( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) - ( ( ( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) / 1.12 ) * 0.12 ),
0 ) ), 4) AS "Bien",
ROUND( SUM( IIF( fvd.U_TipoA = 'S',
( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) - ( ( ( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) / 1.12 ) * 0.12 ),
0 ) ), 4) AS "Servicio",
ROUND( SUM( IIF( fvd.U_TipoA = 'N',
( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) - ( ( ( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) / 1.12 ) * 0.12 ),
0 ) ), 4) AS "No Aplica",
COUNT(fvd.LineNum) AS "Lineas", SUM(fvd.GTotal) AS "FCTotal",
SUM(ISNULL( ncd.GTotal, 0 )) AS "NCTotal"
/* Facturas */
FROM OINV AS fvh
LEFT JOIN NNM1 AS fvs ON fvs.Series = fvh.Series
LEFT JOIN INV1 as fvd ON fvd.DocEntry = fvh.DocEntry
/* Notas de Credito */
LEFT JOIN RIN1 AS ncd ON ncd.BaseEntry = fvh.DocEntry AND ncd.LineNum = fvd.LineNum
WHERE fvh.DocDate BETWEEN ? AND ? /*AND fvh.DocEntry = 1108*/
GROUP BY fvh.DocEntry
Thank you all for your time. I will dismantle my query and re-do it taking into consideration all of your input. Gracias, totales.
You think you can do this in MySQL:
SET #halfvalue := 0;
SELECT Thingie, Value,
(#halfvalue := Value / 2) AS HalfValue,
(#halfvalue / 2) AS HalfOfHalf
FROM Things;
But you are wrong. Why? MySQL -- as with every other database -- does not guarantee the order of evaluation of expression in a SELECT. The documentation even warns about this:
In the following statement, you might think that MySQL will evaluate #a first and then do an assignment second:
SELECT #a, #a:=#a+1, ...;
However, the order of evaluation for expressions involving user variables is undefined.
In both databases, you can use a subquery. In the most recent versions of MySQL (and just about any other database), you can also use a CTE:
SELECT Thingie, Value, HalfValue,
(HalfValue / 2) AS HalfOfHalf
FROM (SELECT t.*, (Value / 2) AS HalfValue
FROM Things t
) t;
The answer is simple: you can't do that in MSSQL, because when you try it you'll get:
Msg 141, Level 15, State 1, Line 3
A SELECT statement that assigns a value to a variable must not be combined with data-retrieval operations.
which you most probably experienced.
The most simple workaround would be:
SELECT Thingie, Value, Value/2, Value/4 from Things
Other method:
select Thingie, Value, HalfValue, HalfValue / 2 from (
SELECT Thingie, Value, Value / 2 HalfValue from Things
) a
No, that doesn't work in SQL. The parameter value is not set until the query completes. You can do it in two steps:
DECLARE #halfvalue FLOAT = 0;
SELECT #halfvalue = ([Value] / 2)
FROM Things ;
SELECT Thingie
, [Value]
, HalfValue = [Value]/2
, HalfAgainValue = #halfvalue / 2
FROM Things ;
I am trying to perform a group summation in mysql , but the nulls are causing issue. I used nullif/ifnull none helped
Here is an example
Group Employee Discipline HardWork Dedication
101 DTF 1 1 1
101 Tim 1 1 0
101 Erk NULL 1 0
101 PMD NULL 1 0
101 NSE 1 1 0
SQL:
SELECT
GROUP,
SUM( EMPLOYEE ),
SUM( DISCIPLINE ),
SUM( HARDWORK ),
SUM( DEDICATION )
FROM
TABLE
GROUP BY
GROUP,
EMPLOYEE,
DISCIPLINE,
HARDWORK,
DEDICATION
Expected result:
101---3----5----1
Actual result
101--5----5-----1
Anyone has any ideas?
Try:
SUM(IFNULL( Discipline, 0 ))
instead of
SUM( DISCIPLINE )
The firt one will take the value 0 is a null is found.
I think your query should be:
SELECT
Group,
COUNT( Employee ) AS EmployeeCountInGroup,
SUM( ISNULL( Discipline, 0 ) ) AS SumDiscipline,
SUM( ISNULL( HardWork, 0 ) ) AS SumHardWork,
SUM( ISNULL( Dedication, 0 ) ) AS SumDedication
FROM
TableName
GROUP BY
Group
Table #1: qa_returns_items
Table #2: qa_returns_residues
I have a long time trying to get this Result:
item_code - item_quantity
2 - 1
3 - 2
IF qa_returns_items.item_code = qa_returns_residues.item_code AND status_code = 11 THEN
item_quantity = qa_returns_items.item_quantity -
qa_returns_residues.item_quantity
ELSEIF qa_returns_items.item_code = qa_returns_residues.item_code AND status_code = 12 THEN
item_quantity = qa_returns_items.item_quantity +
qa_returns_residues.item_quantity
ELSE
show diferendes
END IF
I tried this Query:
select SubQueryAlias.item_code,
item_quantity
from (
select
ri.item_code
, case status_code
when 11 then ri.item_quantity - rr.item_quantity
when 12 then ri.item_quantity + rr.item_quantity
end as item_quantity
from qa_returns_residues rr
left join qa_returns_items ri
on ri.item_code = rr.item_code
WHERE ri.returnlog_code = 1
) as SubQueryAlias
where item_quantity > 0 GROUP BY (item_code);
The query returns this result:
item_code - item_quantity
1 - 2
2 - 2
Try this query. I havn't tested it. It is very difficult what you require. But I have built it from table structure and given condition clause.
select qa_returns_items.item_code,
(CASE status_code
WHEN 11 THEN (qa_returns_items.item_quantity - qa_returns_residues.item_quantity)
WHEN 12 THEN (qa_returns_items.item_quantity + qa_returns_residues.item_quantity) END) as item_quantity ,
qa_returns_residues.item_unitprice,
( qa_returns_residues.item_unitprice * item_quant) as item_subtotal,
(qa_returns_residues.item_discount * item_quantity) as item_discount,
( ( qa_returns_residues.item_unitprice * item_quant) -
(qa_returns_residues.item_discount * item_quantity) ) as item_total
where
item_quantity > 0 AND qa_returns_items.item_code = qa_returns_residues.item_code
Update:
select qa_returns_items.item_code,
(CASE status_code
WHEN 11 THEN (qa_returns_items.item_quantity - qa_returns_residues.item_quantity)
WHEN 12 THEN (qa_returns_items.item_quantity + qa_returns_residues.item_quantity) END) as item_quant ,
qa_returns_residues.item_unitprice,
( qa_returns_residues.item_unitprice * item_quant) as item_subtotal,
(qa_returns_residues.item_discount * item_quantity) as item_discount,
( ( qa_returns_residues.item_unitprice * item_quant) -
(qa_returns_residues.item_discount * item_quantity) ) as item_total
where
(CASE status_code
WHEN 11 THEN (qa_returns_items.item_quantity - qa_returns_residues.item_quantity)
WHEN 12 THEN (qa_returns_items.item_quantity + qa_returns_residues.item_quantity) END) item_quant > 0 AND qa_returns_items.item_code = qa_returns_residues.item_code
In my experience I would advice you to start over with a fresh database, no records and start debugging step by step.
First create the database and the tables. After that insert only 2 records with simple data. Afterwards start debugging.
From what I was able to debug the problem is in your sub-select. In the topic you want to see item_code 2 and 3. That can't happen because:
SELECT ri.item_code,
CASE status_code
WHEN 11 then ri.item_quantity - rr.item_quantity
WHEN 12 then ri.item_quantity + rr.item_quantity
END AS item_quantity
FROM qa_returns_residues rr
LEFT JOIN qa_returns_items ri
ON ri.item_code = rr.item_code
WHERE ri.returnlog_code = 1 // Why do you need this for ?
returns
item_code item_quantity
2 2
1 0
1 0
1 0
1 2
And then the main query selects only the results which have item_quantity > 0.
Thus you get only
item_code item_quantity
1 2
2 2
as a result.
I'm not quite sure what's the purpose of this operation but have in mind that simple solutions are always best!
I solved my problem:
SELECT
item_code,
item_quantity,
item_unitprice,
item_subtotal,
item_discount,
item_total
FROM (
SELECT qa_returns_items.item_code,
qa_returns_items.item_quantity,
qa_returns_items.item_unitprice,
qa_returns_items.item_subtotal,
qa_returns_items.item_discount,
qa_returns_items.item_total
FROM qa_returns_items
WHERE returnlog_code = 1
UNION
SELECT qa_returns_residues.item_code,
qa_returns_residues.item_quantity,
qa_returns_residues.item_unitprice,
qa_returns_residues.item_subtotal,
qa_returns_residues.item_discount,
qa_returns_residues.item_total
FROM qa_returns_residues
WHERE returnlog_code = 1
ORDER BY item_code ASC
)
AS SubQueryAlias
WHERE item_code NOT IN (
SELECT a.item_code
FROM qa_returns_items a
JOIN qa_returns_residues b
ON b.item_code = a.item_code
WHERE a.returnlog_code = 1
AND b.returnlog_code = 1
);
I am writing a query to get the top 10 rated businesses, the number of positive comments for each business, the number of negative comments for each business and the latest comment for each of these businesses.
SELECT comment.bis_id, Sum( Case When comment.rating <= 2 Then 1 Else 0 End ) As NegVotes
, Sum( Case When comment.rating >= 4 Then 1 Else 0 End ) As PosVotes, bis.bis_name
FROM bis, comment
WHERE comment.bis_id = bis.bis_id
GROUP BY bis_id
ORDER BY PosVotes DESC
LIMIT 0, 10";
The above gets positive comments and negative comments, but I can't seem to work out how to get the latest comment as well.
SELECT
c.bis_id
, Sum( Case When c.rating <= 2 Then 1 Else 0 End ) As NegVotes
, Sum( Case When c.rating >= 4 Then 1 Else 0 End ) As PosVotes
, b.bis_name
, cc.last_comment
FROM bis b
INNER JOIN comment c on (c.bis_id = b.bis_id)
INNER JOIN (SELECT c2.bis_id, c2.comment_text as last_comment
FROM comment c2
GROUP BY c2.bis_id
HAVING c2.comment_date = MAX(c2.comment_date) ) cc
ON (cc.bis_id = b.bis_id)
GROUP BY b.bis_id
ORDER BY PosVotes DESC
LIMIT 10 OFFSET 0