SQL - Counting a column twice - sql

I have a table that has a column called 'status'. This can be set to 0 or 1
Is it possible for me to count both the 0's and 1's in a single query?
Thanks in advance
James

Yes, just group on the value of status:
SELECT status, COUNT(*)
FROM yourtable
GROUP BY status
That will give you exactly two rows since the value can only be 0 or 1, and the COUNT(*) column will be the number of times each status value appears in the table.

SELECT SUM(CASE WHEN status = 0 THEN 1 ELSE 0 END) AS 'number of zeroes',
SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) AS 'number of ones'
FROM yourtable;

Related

Oracle (SQL): How to get SQL query syntax

A table (ex: A) has three columns id, name, amount. Amount has some +ve,-ve and zero values. How to write a query to get the amount in such a way that it gives as a result first +ve then -ve then zeros? PFA for the sample table.
Thanks in advance
If you want 3 groups one after the other:
SELECT *
FROM tablename
ORDER BY
(CASE
WHEN amount > 0 then 1
WHEN amount < 0 then 2
ELSE 3
END),
Id;
Are you just looking for order by with a case expression?
select a.*
from a
order by (case when a.amount > 0 then 1
when a.amount < 0 then 2
else 3
end),
a.amount desc;

How to group and get count of rows based on value of one column in sql server

I have a table of requests with columns RequestType,status .Status column values can be in-progress,complated etc.
I would like to get the list like
RequestType In-Progress Completed Total
Type1 10 5 15
Type2 10 10 20
I tried with group by using the 2 columns( RequestType,status) ,but it does not give me the exact result.
Please help me with the sql query.
Thanks in advance
Subin
One way to do it is using conditional aggrigation:
SELECT RequestType,
SUM(CASE WHEN Status = 'In-Progress' THEN 1 ELSE 0 END) As 'In-Progress',
SUM(CASE WHEN Status = 'Completed' THEN 1 ELSE 0 END) As 'Completed',
COUNT(Status) As 'Total'
FROM TableName
WHERE Status IN('In-Progress', 'Completed')
GROUP BY RequestType
Use PIVOT
select *, [In-Progress]+[Completed] total
from TableName
pivot ( count(status) for status in ([In-Progress], [Completed])) as p

Stuck on a slightly tricky query, trying to ignore multiple results based on a single field

Here is a simple database representation of what I'm stuck on:
IDNumber TimeSpent Completed
1 0 No
1 0 No
1 2 No
2 0 No
3 0 No
I'm currently querying the database as such...
"SELECT Distinct (IDNumber) AS Info FROM TestTable
ORDER BY WorkOrderNumber";
And it gives me back the results
1
2
3
Which is expected.
Now, I'd like to adjust it to where any instance of an IDNumber that have TimeSpent != 0 or Completed != No means that the IDNumber isn't grabbed at all. So for example in the database given, since TimeSpent = 2, I don't want IDNumber 1 to be returned in my query at all.
My first instinct was to jump to something like this...
"SELECT Distinct (IDNumber) AS Info FROM TestTable
WHERE TimeSpent='0' AND Completed='No'
ORDER BY WorkOrderNumber";
But obviously that wouldn't work. It would correctly ignore one of the IDNumber 1's but since two others still satisfy the WHERE clause it would still return 1.
Any pointers here?
SELECT DISTINCT IDNumber
FROM TestTable
WHERE IDNumber NOT IN
(SELECT IDNUmber FROM TestTable WHERE TimeSPent <> 0 OR Completed <> 'No')
You can do this with an aggregation, using a having clause:
select IDNumber
from TestTable
group by IDNumber
having sum(case when TimeSpent = 0 then 1 else 0 end) = 0 and
sum(case when Completed = 'No' then 1 else 0 end) = 0
The having clause is counting the number of rows that meet each condition. The = 0 is simply saying that there are no matches.
I prefer the aggregation method because it is more flexible in terms of the conditions that you can set on the groups.

SQL Count with multiple conditions then join

Quick one,
I have a table, with the following structure
id lid taken
1 1 0
1 1 0
1 1 1
1 1 1
1 2 1
Pretty simply so far right?
I need to query the taken/available from the lid of 1, which should return
taken available
2 2
I know I can simply do two counts and join them, but is there a more proficient way of doing this rather than two separate queries?
I was looking at the following type of format, but I can not for the life of me get it executed in SQL...
SELECT
COUNT(case taken=1) AS taken,
COUNT(case taken=0) AS available FROM table
WHERE
lid=1
Thank you SO much.
You can do this:
SELECT taken, COUNT(*) AS count
FROM table
WHERE lid = 1
GROUP BY taken
This will return two rows:
taken count
0 2
1 2
Each count corresponds to how many times that particular taken value was seen.
Your query is correct just needs juggling a bit:
SELECT
SUM(case taken WHEN 1 THEN 1 ELSE 0 END) AS taken,
SUM(case taken WHEN 1 THEN 0 ELSE 1 END) AS available FROM table
WHERE
lid=1
Alternatively you could do:
SELECT
SUM(taken) AS taken,
COUNT(id) - SUM(taken) AS available
FROM table
WHERE
lid=1
SELECT
SUM(case WHEN taken=1 THEN 1 ELSE 0 END) AS taken,
SUM(case WHEN taken=0 THEN 1 ELSE 0 END) AS available
FROM table
WHERE lid=1
Weird application of CTE's:
WITH lid AS (
SELECT DISTINCT lid FROM taken
)
, tak AS (
SELECT lid,taken , COUNT(*) AS cnt
FROM taken t0
GROUP BY lid,taken
)
SELECT l.lid
, COALESCE(a0.cnt, 0) AS available
, COALESCE(a1.cnt, 0) AS taken
FROM lid l
LEFT JOIN tak a0 ON a0.lid=l.lid AND a0.taken = 0
LEFT JOIN tak a1 ON a1.lid=l.lid AND a1.taken = 1
WHERE l.lid=1
;

SQL - Count( ) issue

I have a table with a charge/credit column:
Item | PriceVal | CostVal | CHARGE_CODE
1 5 3 CH
2 8 5 CH
1 -5 -3 CR
3 7 1 CH
4 15 10 CH
1 5 3 CH
I've got the query I need to get the NET price and cost, but I'm also interested in the NET charges. Right now I have:
SELECT Item, SUM(PriceVal), SUM(CostVal)
FROM Table
GROUP BY Item
How do I get another column with the value
COUNT(SUM(CHARGE_CODE=CH)-SUM(CHARGE_CODE=CR))
I'm at a loss.
count() is going to count one for every value thats not null, so I don't think thats exactly what you want. Take the count out and just take the
sum(case when charge_code = CH then costval else 0 end)
- sum(case when charge_code = 'CR' then costval else 0 end)
Since you have the dollar values entered as negatives in the table already, you can use the simple formula:
select
Item,
sum(PriceVal),
sum(CostVal),
sum(PriceVal-CostVal)
from Table
group by Item
I don't believe you should be subtracting the credit items as they're already negative.
If you really do want want the net count of transactions:
select
Item,
sum(PriceVal),
sum(CostVal),
sum(case when charge_code = 'CH' then 1 else 0 end) -
sum(case when charge_code = 'CR' then -1 else 0 end)
from Table
group by Item
or, if there are only two charge codes, substitute:
sum(case when charge_code = 'CH' then 1 else -1 end)
for the last column.
Not 100% sure what you want, but you can count only certain rows like this:
SELECT COUNT(IF(CHARGE_CODE=CH,1,NULL)) ...
And similarly sum certain values from certain rows like this:
SELECT SUM(IF(CHARGE_CODE=CH,PriceVal,0)) ...