SQL query case when at least one - sql

How to use CASE to show 'debtor' if at least one of the invoices is not paid (Invoice_Status = 1)?
*(A customer has multiple invoices)
Here's the query to show the an Id_Customer and the status of his multiple invoices, but this repeats the Id_Customer for each invoice he has
SELECT Id_Customer,
CASE Invoice_Status
WHEN 1 THEN 'Debtor'
ELSE 'No debts'
END AS Status
FROM Tb_Invoices
ORDER BY Id_Customer
GO

You need to use an aggregate (min, max, count etc) on Invoice_Status, then map that value via you case statement. You haven't told us about your schema or data so we can't really help you more than that. I.e. something like this:
SELECT CASE
WHEN count(Invoice_Status = 1) > 0 THEN 'Dector'
ELSE 'No debts'
END
FROM Tb_Invoices
ORDER BY Id_Customer

Related

Group By with Case Statements SQL Server

I would like to group by with the case statements in SQL Server. I created cases that's my revenue range. I'd like to calculate the number of sales orders within all these revenue ranges(cases)
Below please find my queries:
Select
sum(OrderQuantity) as Orders,
case when (sum(SalesAmount-TaxAmt-Freight)<100 and sum(SalesAmount-TaxAmt-Freight)>=0) then '$0-$100'
when (sum(SalesAmount-TaxAmt-Freight)>=100 and sum(SalesAmount-TaxAmt-Freight)<500) then '$100-$500'
when (sum(SalesAmount-TaxAmt-Freight)>=500 and sum(SalesAmount-TaxAmt-Freight)<1000) then '$500-$1000'
when (sum(SalesAmount-TaxAmt-Freight)>=1000 and sum(SalesAmount-TaxAmt-Freight)<2500) then '$1000-$2500'
when (sum(SalesAmount-TaxAmt-Freight)>=2500 and sum(SalesAmount-TaxAmt-Freight)<5000) then '$2500-$5000'
when (sum(SalesAmount-TaxAmt-Freight)>=5000 and sum(SalesAmount-TaxAmt-Freight)<10000) then '$5000-$10000'
when (sum(SalesAmount-TaxAmt-Freight)>=10000 and sum(SalesAmount-TaxAmt-Freight)<50000) then '$10000-$50000'
when (sum(SalesAmount-TaxAmt-Freight)>=50000 and sum(SalesAmount-TaxAmt-Freight)<100000) then '$50000-$100000'
when (sum(SalesAmount-TaxAmt-Freight)>=100000) then '>$100000'
end as SalesAmountCategory
From
dbo.FactResellerSales
group by
SalesAmountCategory;
I expect to get the result like:
result example
I keep getting errors when i try to group by based on the case statements. The error is "Invalid column name 'SalesAmountCategory'". How can i do that? Many thanks in advance!
It looks like you want to know number of orders in each category
So, you need first to map each order to category and then group by it, like that:
select SalesAmountCategory, count(*) from
(
Select case
when ((SalesAmount-TaxAmt-Freight)>=100000) then '>$100000'
when ((SalesAmount-TaxAmt-Freight)>=50000) then '$50000-$100000'
when ((SalesAmount-TaxAmt-Freight)>=10000) then '$10000-$50000'
when ((SalesAmount-TaxAmt-Freight)>=5000) then '$5000-$10000'
when ((SalesAmount-TaxAmt-Freight)>=2500) then '$2500-$5000'
when ((SalesAmount-TaxAmt-Freight)>=1000) then '$1000-$2500'
when ((SalesAmount-TaxAmt-Freight)>=500) then '$500-$1000'
when ((SalesAmount-TaxAmt-Freight)>=100) then '$100-$500'
when ((SalesAmount-TaxAmt-Freight)<100) then '$0-$100'
end as SalesAmountCategory
From dbo.FactResellerSales
) as t
group by SalesAmountCategory

AND OR SQL operator with multiple records

I have the following query where if brand1/camp1 taken individually, query returns the correct value but if I specify more than one brand or campaigns, it returns some other number and I am not sure what the math is behind that. It is not the total of the two either.
I think it is IN operator that is specifying OR with "," as opposed to what I require it to do which is consider AND
select campaign,
sum(case when campaign in ('camp1', 'camp2') and description in ('brand1', 'brand2') then orders else 0 end) as brand_convs
from data.camp_results
where campaign in ('camp1', 'camp2') and channel='prog' and type='sbc'
group by campaign
having brand_convs > 0
order by brand_convs desc;
Any thoughts?
The problem is in the IN part as you suspected: The two IN operators do not affect eachother in any way, so campaign can be camp1 while description is brand2.
If your DBMS supports multiple columns in an IN statement, you use a single IN statement:
SELECT campaign, SUM(
CASE WHEN (campaign, description) IN (
('camp1', 'brand1'),
('camp2', 'brand2')
) THEN orders ELSE 0 END
) [rest of query...]
If not, you're probably going to have to use ANDs and ORs
SELECT campaign, SUM(
CASE WHEN
(campaign='camp1' AND description='brand1')
OR (campaign='camp2' AND description='brand2')
THEN orders ELSE 0 END
) [rest of query...]

SQL aggregation with case statement and group by

I'm trying to understand the problem with this code:
SELECT COUNT(CASE liveIn.state
WHEN ("NY" OR "NJ") THEN "group1"
WHEN ("NC" or "SC") THEN "group2"
END) AS state_groups
FROM (SELECT DISTINCT user_guid, state
FROM users
WHERE country="US" AND country IS NOT NULL) AS liveIn
GROUP BY state_groups;
The error I get is: "Can't group on 'state_groups'"
I have other code that solve my problem which look like this (but I'm trying to understand the problem with the one above):
SELECT COUNT(DISTINCT user_guid),
CASE
WHEN (state="NY" OR state="NJ") THEN "group1"
WHEN (state="NC" OR state="SC") THEN "group2"
END AS state_groups
FROM users
WHERE country="US" AND country IS NOT NULL
GROUP BY state_groups;
my output should look like this:
TKS!
P.S.- this is part of coursera sql learning course, so I'm working on Jupyter.
Your case when returns group values but they are not useful when wrapped in a count, as they will all contribute as 1 to it. Furthermore, you cannot group by the aggregate you want to calculate based on a group. Note that you only have 1 column in your first SQL. You should have 2: one identifying the group, and the other the count. You merged the two into one, and that does not make sense.
This would be a valid alternative:
SELECT CASE state
WHEN "NY" THEN "group1"
WHEN "NJ" THEN "group1"
WHEN "NC" THEN "group2"
WHEN "SC" THEN "group2"
ELSE "others"
END AS state_group,
COUNT(DISTINCT user_guid) AS user_count
FROM USERS
WHERE country = "US"
GROUP BY state_group
SQL fiddle
Note that if you put an or in this variation of the when clause, the second term of that or will be evaluated separately, and make the condition true, so all values will then end up in group1.
You could use the other variant of the case when syntax, where you can use or or even better, in:
SELECT CASE WHEN state IN ("NY", "NJ") THEN "group1"
WHEN state IN ("NC", "SC") THEN "group2"
ELSE "others"
END AS state_group,
COUNT(DISTINCT user_guid) AS user_count
FROM USERS
WHERE country = "US"
GROUP BY state_group
Note that in this syntax, there is nothing between the case and the first when.

conditional select between multiple fields

I have a table with a certain flag called FL_virtual, if this flag equals 1 i need to get my stock in a special way using a function
now i want to make a select statement with it but depending on this flag i need to adjust my select to use a certain function instead of a subquery
so presume i start with this select statement
select product_name,..(other options from the product table),
(select sum(qy_stock) from STOCK where warehouse_id = 1) as 'qy_stock_internal',
(select sum(qy_stock) from STOCK where warehouse_id = 2) as qy_stock_external
From product
now i need to change the subquery (qy_stock) with a call to a function when the fl_virtual flag is 1
so that it becomes like this
select product_name,..(other options from the product table),
FN_GET_stock_PRODUCT(1) as qy_stock_internal,
FN_GET_stock_PRODUCT(2) as qy_stock_external
from product
so i thought a simple if then else structure will do but for some reason i can't get it to work
this is how i thought it would look
select product_name,..(other options from the product table),
IF fl_virtual > 0 THEN
(select sum(qy_stock) from STOCK where warehouse_id = 1) as 'qy_stock_internal',
(select sum(qy_stock) from STOCK where warehouse_id = 2) as qy_stock_external
ELSE
FN_GET_stock_PRODUCT(1) as qy_stock_internal,
FN_GET_stock_PRODUCT(2) as qy_stock_external
END IF
but it doesn't work , anyone got an idea?
You're close - just use CASE instead of IF (you have to repeat your condition, since you cannot easily return two columns from a single CASE (see P.S.):
select product_name,
..(other options from the product table),
(CASE
WHEN fl_virtual > 0 THEN
(select sum(qy_stock) from STOCK where warehouse_id = 1)
ELSE
FN_GET_stock_PRODUCT(1)
END) as qy_stock_internal,
(CASE
WHEN fl_virtual > 0 THEN
(select sum(qy_stock) from STOCK where warehouse_id = 2)
ELSE
FN_GET_stock_PRODUCT(2)
END) as qy_stock_external
P.S.: It is possible to return multiple values from a single CASE, e.g. using Object Types, but that's stuff for a different question :-)
Best way is to use a union select with those 2 different queries and contitions.
Btw. the names stock and warehouse look like a typical school work examin.

Sql sum and show result in many column

If I have a table look like in this page and I wanna sum the orderPrice by each customer.
Then I wanna show the result show in one row look like this.
How can I write the query.
Ps. Sorry for show everything on web.
Since you did not put any restrictions on how that information should be produced, you can do the following:
Select Sum( Case When Customer = 'Hansen' Then OrderPrice End ) As sumHansen
, Sum( Case When Customer = 'Nilsen' Then OrderPrice End ) As sumNilsen
, Sum( Case When Customer = 'Jensen' Then OrderPrice End ) As sumJensen
From CustomerTotals
If your'e using SQL Server you can use PIVOT statement.