Sum statement counts everything, or northing - sql

I am almost finished with my project, but i still have one issue left.
I need to create a summary with an sql code. The code is like this:
"SELECT SUM(prices of a column), select others FROM blablabla WHERE condintion 1 is true OR condition 2 is true OR condition 3 is true GROUP BY blablabla;"
The problem is, is that i can't use the above because of the OR. Whenever i use OR, it see's that condintion 1 for example is true, so he will ignore the rest of the conditions, but i need them to to see if they are true. The problem with using a "AND" instead of an "OR" causes to set the result to nothing because all three can't always be true.
So the bottomline is, My query needs to count some fields in a column where a field meets a condition. I use multiple conditions because there are diffrent kinds of products, but i somehow can't use the conditions al togheter because the statement counts everything whever one condition is met, or counts nothing because they can't always be true all three of them.
how do i fix this?
thanks

SELECT SUM(prices column) as Total
FROM yourTable
WHERE condition1 is true
GROUP BY columnBLabla
UNION ALL
SELECT SUM(prices column)
FROM yourTable
WHERE condition2 is true
GROUP BY columnBLabla
UNION ALL
SELECT SUM(prices column)
FROM yourTable
WHERE condition3 is true
GROUP BY columnBLabla
Result
Total
100 -- total price when condition 1 is true
230 -- total price when condition2 is true
900 -- total price when condition 3 is true

I'm not sure if I have completely understand the question, I think this is what you are looking for
SELECT SUM(prices of a column)
FROM blablabla
WHERE
(condintion 1 is true OR condition 2 is true)
AND
(condintion 1 is true OR condition 3 is true)
AND
(condintion 2 is true OR condition 3 is true)
GROUP BY blablabla;
OR may be
SELECT SUM(prices of a column)
FROM blablabla
WHERE
(condintion 1 is true AND condition 2 is true)
OR
(condintion 1 is true AND condition 3 is true)
OR
(condintion 2 is true AND condition 3 is true)
GROUP BY blablabla;

I may be misunderstanding but, could you use a case statement? You could put each of the conditions in its own "When X is true A" statement. Then by varying/or not varying the A you could make category to summarize on.

How about this?
SELECT
SUM(CASE WHEN condition1 THEN prices_of_a_column ELSE 0 END) AS prices1,
SUM(CASE WHEN condition2 THEN prices_of_a_column ELSE 0 END) AS prices2,
SUM(CASE WHEN condition3 THEN prices_of_a_column ELSE 0 END) AS prices3
FROM blabla
GROUP BY blabla

Related

Using case statement to compare columns

I'd like to use a case statement to compare multiple rows on 2 columns. For example, if row 1 column 1 and row 2 column 1 match but row 1 column 2 and row 2 column 2 don't, then xx. I have
CASE
WHEN (pprof.description = pprof.description and PCtrl.[sequence] <> PCtrl.[sequence])
THEN xx
but that doesn't return any values, which I know to be incorrect. I'm new to SQL so apologies if I've got this all wrong.
Edit:
Here's some sample data:
Column 1
Column 2
Column 3
123
-A
-No
123
-B
-Yes
Can't figure out the formatting here but there are 3 columns of data above. I'd like the case statement to evaluate whether column 1 match in 2 different rows (i.e., 123 = 123) and also whether column 2 doesn't (A <> B) and if both those conditions are true, return a value in column 3 (in my case, make the No a Yes, since 123-B is Yes). It might be worth noting that the "Yes" and "No" themselves are built into the larger case statement here:
(CASE WHEN tenure.description not in ('casual','co-op','fswep') THEN CASE WHEN (pprof.description = pprof.description and PCtrl.[sequence] <> PCtrl.[sequence])
THEN CASE WHEN (PEmp.Employee_Number = PEmp3.Supervisor_Number) THEN 'Yes' ELSE 'No' END END END) as 'People Manager'
You will want to do a self join here. Without seeing your data, I can't really give you an answer, but you want something like this.
Update A
Set column_3 = 'YES' /* or put CASE statement here /*
FROM pprof A
INNER JOIN pprof B
ON a.description = b.description
AND a.sequence != b.sequence
You may need more join conditions depending on the form of your data and what you want.

How multiple CASE WHEN scenario works in SQL?

If in a query we have 2 case scenario satisfying the condition, which one will be picked by the SQL to show the output ?
sample Query :
SELECT
CASE
WHEN field1 = 'a' THEN 1
WHEN field2 = 'a' THEN 2
ELSE 3
END
from table ;
In SQL they will be evaluated in the order they are written so the first match wins.
As soon as a condition is true within your case conditions it will ignore all the later conditions.
If field1='a' then it will return 1 even if field2='a'. But if field1<>'a' and field2='a' then it will return 2 and only if field1 and field2 are both not 'a' then it will return 3.
I am assuming that field1 and field2 are column names.

Applying Logic to Grouped SQL Results

Looking for some Oracle SQL theoretical help on the best way to handle a grouped result set. I understand why it groups the way it does, but I'm trying to figure out if there's a way to
I have a table that lists the activity of some cost centers. It looks like this:
Company Object Sub July August
A 1 20 50
A 1 10 0
A 1 10 0 20
B 1 0 0
I then need to flag whether or not there was activity in August. So I'm writing a CASE statement where if August = 0 THEN 'FALSE' ELSE 'TRUE'. Then I need to group all records by Company, Object, and Sub. The Cumulative column is a SUM of both July and August. However, my output looks like this:
Company Object Sub SUM ActivityFlag
A 1 70 TRUE
A 1 10 FALSE
A 1 10 20 TRUE
B 1 0 FALSE
What I need is this:
Company Object Sub August ActivityFlag
A 1 80 TRUE
A 1 10 20 TRUE
B 1 0 FALSE
Obviously, this is a simplified example of a much larger issue, but I'm trying to think through this problem theoretically so I can apply similar logic to my actual issue.
Is there a good SQL method for adding the August amount for rows 1 and 2, and then selecting TRUE so that this appears on a single row? I hope this makes sense.
use aggregation
select company,object,sub,sum(july+august),
max(case when august>0 then 'True' else 'false' end)
from table_name group by company,object,sub
If you are flagging your detail with the case statement you can either put the case in a sum similar to:
MAX(CASE WHEN August = 0 THEN 1 ELSE 0 END)
Another way if to aggregate the flag upward in an inner query:
SELECT IsAugust = MAX(IsAugust) FROM
(
...
IsAugust = CASE WHEN August=0 THEN 1 ELSE 0 END
...
)AS X
GROUP BY...

Counting checked items in database

In my database I have table with multiple "yes/no" rows on which I would like to run some selection check if they are selected or not.
ITEM ORDERED ORDER_ID
item1 true 1
item2 false 1
item3 true 2
item4 true 3
item5 true 4
item6 true 4
In datagridview in my code I will like to achieve this.
ORDER STATUS
1 not ordered
2 ordered
3 ordered
4 ordered
In my code I will like to go through all orders and check if status of ordered items on that order is true. If all items on some order have status true, then i will like to set another flag that I have in ORDER table to true(ordered). Which is the most elegant way to solve this problem? If you have some example of this like problem I will really appreciate it. Thanks in advance.
It appears STATUS means whether all rows for that ORDER_ID have ORDERED = True. If that is correct, I think you can get what you need with an Access aggregate (GROUP BY) query.
True is stored as -1 and False is stored as 0. So if the maximum ORDERED value for any ORDER_ID is 0, you know there is at least one item for that order which has not yet been ordered. If the maximum is -1, then all items have been ordered.
Start with a query to determine Max(ORDERED) for each ORDER_ID.
SELECT y.ORDER_ID, Max(y.ORDERED) AS MaxOfORDERED
FROM YourTable AS y
GROUP BY y.ORDER_ID;
Once you have that working, use it as a subquery in another with an IIf expression to transform MaxOfORDERED to the STATUS text you want.
SELECT
sub.ORDER_ID,
IIf(sub.MaxOfORDERED = 0, 'not ordered', 'ordered') AS STATUS
FROM
(
SELECT y.ORDER_ID, Max(y.ORDERED) AS MaxOfORDERED
FROM YourTable21030926a AS y
GROUP BY y.ORDER_ID
) AS sub
ORDER BY sub.ORDER_ID;

T-SQL SUM All with a Conditional COUNT

I have a query that produces the following:
Team | Member | Cancelled | Rate
-----------------------------------
1 John FALSE 150
1 Bill TRUE 10
2 Sarah FALSE 145
2 James FALSE 110
2 Ashley TRUE 0
What I need is to select the count of members for a team where cancelled is false and the sum of the rate regardless of cancelled status...something like this:
SELECT
Team,
COUNT(Member), --WHERE Cancelled = FALSE
SUM(Rate) --All Rows
FROM
[QUERY]
GROUP BY
Team
So the result would look like this:
Team | CountOfMember | SumOfRate
----------------------------------
1 1 160
2 2 255
This is just an example. The real query has multiple complex joins. I know I could do one query for the sum of the rate and then another for the count and then join the results of those two together, but is there a simpler way that would be less taxing and not cause me to copy and paste an already complex query?
You want a conditional sum, something like this:
sum(case when cancelled = 'false' then 1 else 0 end)
The reason for using sum(). The sum() is processing the records and adding a value, either 0 or 1 for every record. The value depends on the valued of cancelled. When it is false, then the sum() increments by 1 -- counting the number of such values.
You can do something similar with count(), like this:
count(case when cancelled = 'false' then cancelled end)
The trick here is that count() counts the number of non-NULL values. The then clause can be anything that is not NULL -- cancelled, the constant 1, or some other field. Without an else, any other value is turned into NULL and not counted.
I have always preferred the sum() version over the count() version, because I think it is more explicit. In other dialects of SQL, you can sometimes shorten it to:
sum(cancelled = 'false')
which, once you get used to it, makes a lot of sense.