SQL Math Issue During Sum - Works when removing either of the conditions - sql

I'm using MS SQL, and here is my query...
SELECT SUM(Quantity) FROM table1
WHERE [item_no]='0052556'
AND [qty_to_ship] > 0
AND [type] = 5
Interestingly, the query as it stands above returns 'NULL'...however, if I remove either one of the last 2 conditions it works fine (returns a real number)
to clarify, these queries work fine:
SELECT SUM(Quantity) FROM table1
WHERE [item_no]='0052556'
AND [type] = 5
and
SELECT SUM(Quantity) FROM table1
WHERE [item_no]='0052556'
AND [qty_to_ship] > 0
also note: 'type' is a PK, int, not null
what might be causing this?

Do you have a record that fullfils all the requirement in your (most restrictive) WHERE?
If not - there's your anwer.
Edit: RedFilter's comment is correct is well. You can add your own logic (ISNULL, etc.) in the SELECT Portion to change NULL to values you like (like 0, for instance)

Simply, there are no records that match both clauses
[qty_to_ship] > 0
AND [type] = 5
or the records that do match contain NULL in the Quantity field.

Please check if the below query returns you any rows.
SELECT * FROM table1
WHERE [item_no]='0052556'
AND [qty_to_ship] > 0
AND [type] = 5
If this is returning you atleast one row, then the SUM should not return NULL

Related

How to get 0 if no row found from sql query in sql server

I am getting blank value with this query from sql server
SELECT TOP 1 Amount from PaymentDetails WHERE Id = '5678'
it has no row,that is why its returning blank,So I want if no row then it should return 0
I already tried with COALESCE ,but its not working
how to solve this?
You are selecting an arbitrary amount, so one method is aggregation:
SELECT COALESCE(MAX(Amount), 0)
FROM PaymentDetails
WHERE Id = '5678';
Note that if id is a number, then don't use single quotes for the comparison.
To be honest, I would expect SUM() to be more useful than an arbitrary value:
SELECT COALESCE(SUM(Amount), 0)
FROM PaymentDetails
WHERE Id = '5678';
You can wrap the subquery in an ISNULL:
SELECT ISNULL((SELECT TOP 1 Amount from PaymentDetails WHERE Id = '5678' ORDER BY ????),0) AS Amount;
Don't forget to add a column (or columns) to your ORDER BY as otherwise you will get inconsistent results when more than one row has the same value for Id. If Id is unique, however, then remove both the TOP and ORDER BY as they aren't needed.
You should never, however, use TOP without an ORDER BY unless you are "happy" with inconsistent results.

PostgreSQL - Handling empty query result

I am quite new to SQL and I am currently working on some survey results with PostgreSQL. I need to calculate percentages of each option from 5-point scale for all survey questions. I have a table with respondentid, questionid, question response value. Demographic info needed for filtering datacut is retrieved from another table. Then query is passed to result table. All queries texts for specific datacuts are generated by VBA script.
It works OK in general, however there's one problematic case - when there are no respondents for specific cut and I receive empty table as query result. If respondent count is greater than 0 but lower than calculation threshold (5 respondents) I am getting table full of NULLs which is OK. For 0 respondents I get 0 rows as result and nothing is passed to result table and it causes some displacement in final table. I am able to track such cuts as I am also calculating respondent number for overall datacut and storing it in another table. But is there anything I can do at this point - generate somehow table full of NULLs which could be inserted into result table when needed?
Thanks in advance and sorry for clumsiness in code.
WITH ItemScores AS (
SELECT
rsp.questionid,
CASE WHEN SUM(CASE WHEN rsp.respvalue >= 0 THEN 1 ELSE 0 END) < 5 THEN
NULL
ELSE
ROUND(SUM(CASE WHEN rsp.respvalue = 5 THEN 1 ELSE 0 END)/CAST(SUM(CASE
WHEN rsp.respvalue >= 0 THEN 1 ELSE 0 END) AS DECIMAL),2)
END AS 5spercentage,
... and so on for frequencies of 1s,2s,3s and 4s
SUM(CASE WHEN rsp.respvalue >= 0 THEN 1 ELSE 0 END) AS QuestionTotalAnswers
FROM (
some filtering applied here [...]
) AS rsp
GROUP BY rsp.questionid
ORDER BY rsp.questionid;
INSERT INTO results_items SELECT * from ItemScores;
If you want to ensure that the questionid column won't be empty, then you must call a cte with its plain values and then left join with the table that actually you are using to make the aggregations, calcs etc. So it will generate for sure the first list and then join its values.
The example of its concept would be something like:
with calcs as (
select questionid, sum(respvalue) as sum_per_question
from rsp
group by questionid)
select distinct rsp.questionid, calcs.sum_per_question
from rsp
left join calcs on rsp.questionid = calcs.questionid

Emulate subquery with no main table in access

I can do this in SQL Server:
SELECT 'HERRAMIENTA ELÉCTRICA' AS TIPO_PRODUCTO,
0 AS DEPRECIACION,
(select sum(empid) from HR.employees) STOCK
but in Access the same query show me the next error:
Query input must contain at least one table or query
So which could be the best form to emulate this? Make a query with any other table looks dirty for me.
EDIT 1:, HR.employees It may no have data, but i want show constants ('HERRAMIENTA ELÉCTRICA',''0') and 0 in the third column, maybe using isnull and this is not the problem here.
Why not to select directly:
select 'HERRAMIENTA ELÉCTRICA' AS TIPO_PRODUCTO,
0 AS DEPRECIACION,
IIF(ISNULL(sum(empid)), 0, sum(empid)) AS STOCK
from HR.employees
This simply doesn't work in Access. You need a FROM clause.
So you need to have a dummy table with one record, even if you don't use a single field from that table.
SELECT 'HERRAMIENTA ELÉCTRICA' AS TIPO_PRODUCTO,
0 AS DEPRECIACION,
(select sum(empid) from HR.employees) STOCK
FROM Dummy_Table
Using this example as empty table:
with employ as
(select 2 as col from dual
minus
select 2 as col from dual)
The query is this one:
select 'HERRAM' as tipo,
0 as deprec,
coalesce(sum(col), 0) as STOCK
from employ;
coalesce(x, value) sets the column to value when X is null
In Access, you can use a system table, and Val and Nz for the zero value:
SELECT TOP 1
'HERRAMIENTA ELÉCTRICA' AS TIPO_PRODUCTO,
0 AS DEPRECIACION,
Val(Nz((select sum(empid) from HR.employees), 0)) AS STOCK
FROM
MSysObjects

SQL query to add or subtract values based on another field

I need to calculate the net total of a column-- sounds simple. The problem is that some of the values should be negative, as are marked in a separate column. For example, the table below would yield a result of (4+3-5+2-2 = 2). I've tried doing this with subqueries in the select clause, but it seems unnecessarily complex and difficult to expand when I start adding in analysis for other parts of my table. Any help is much appreciated!
Sign Value
Pos 4
Pos 3
Neg 5
Pos 2
Neg 2
Using a CASE statement should work in most versions of sql:
SELECT SUM( CASE
WHEN t.Sign = 'Pos' THEN t.Value
ELSE t.Value * -1
END
) AS Total
FROM YourTable AS t
Try this:
SELECT SUM(IF(sign = 'Pos', Value, Value * (-1))) as total FROM table
I am adding rows from a single field in a table based on values from another field in the same table using oracle 11g as database and sql developer as user interface.
This works:
SELECT COUNTRY_ID, SUM(
CASE
WHEN ACCOUNT IN 'PTBI' THEN AMOUNT
WHEN ACCOUNT IN 'MLS_ENT' THEN AMOUNT
WHEN ACCOUNT IN 'VAL_ALLOW' THEN AMOUNT
WHEN ACCOUNT IN 'RSC_DEV' THEN AMOUNT * -1
END) AS TI
FROM SAMP_TAX_F4
GROUP BY COUNTRY_ID;
select a= sum(Value) where Sign like 'pos'
select b = sum(Value) where Signe like 'neg'
select total = a-b
this is abit sql-agnostic, since you didnt say which db you are using, but it should be easy to adapat it to any db out there.

SQL select statement filtering

Ok, so I'm trying to select an amount of rows from a column that holds the value 3, but only if there are no rows containing 10 or 4, if there are rows containing 10 or 4 I only want to show those.
What would be a good syntax to do that? So far I've been attempting a CASE WHEN statement, but I can't seem to figure it out.
Any help would be greatly appreciated.
(My database is in an MS SQL 2008 server)
Use a union all:
select
// columns
from YourTable
where YourColumn = 3 and not exists (
select 1 from YourTable where YourColumn = 10 or YourColumn = 4)
union all
select
// columns
from YourTable
where YourColumn = 10 or YourColumn = 4
FYI: Orginal question title was "SQL CASE WHEN NULL - question"
CASE WHEN YourColumn IS NULL THEN x ELSE y END
Since there is nothing that compares to NULL and returns true (not even NULL itself), you cant't do
CASE YourColumn WHEN NULL THEN x ELSE y END
only
CASE ISNULL(YourColumn, '') WHEN '' THEN x ELSE y END
but then you lose the ability to differentiate between NULL and the (in this example) empty string.
Depending on the size of your table and its indexes, it may be more efficient to calculate which values you want before the query
declare #UseThree as bit = 1;
if exists (select 1 from testtable where rowval in (10,4))
set #UseThree = 0;
select COUNT(*)
from testtable
where (#UseThree = 1 AND rowval=3)
OR
(#UseThree = 0 AND rowval in (10,4))
The simplest solution would be to do this in two queries:
SELECT ... FROM YourTable WHERE SomeColumn IN (10,4)
If and only if the above query yields no results, then run the second query:
SELECT ... FROM YourTable WHERE SomeColumn = 3
Running two queries may seem "inelegant" but it has advantages:
It's easy to code
It's easy to debug
It often has better performance than a very complex solution
It's easy to understand for a programmer who has to maintain the code after you.
Running two queries may seem like it has extra overhead, but also consider that you won't run the second query every time -- only if the first query has an empty result. If you use an expensive single-query solution, remember that it will incur that expense every time.