SQL Select COUNT(Value=Value) Possible? - sql

I want to Count all the rows that only have the value I want like this:
SELECT Users.Balance,
Users.FreeBids,
COUNT(Bids.Burned = 0) AS 'ActiveBids',
COUNT(Bids.Burned = 1) AS 'BurnedBids'
FROM Users
INNER JOIN Bids
ON Users.ID = Bids.BidderID
WHERE Users.ID = 2
GROUP BY Users.Balance,
Users.FreeBids
It says "Invalid Syntax Neat '=' It works perfectly without the '='.
How can I count the rows that Burned=1 in them and Burned=0 in them?
Thanks,
Dan

Use a CASE statement
COUNT(CASE WHEN Bids.Burned=0 THEN 1 END) AS 'ActiveBids',
COUNT(CASE WHEN Bids.Burned=1 THEN 1 END) AS 'BurnedBids'
There is an implicit ELSE NULL. COUNT only counts NOT NULL values so this will give you the result you need.

Related

Is there a way to contruct this kind of result using group by in sql?

I have a table which consists of data where in I'm having trouble counting the corresponding rows.
Here is the sample table:
I am expecting an output like this:
You can do conditional aggregation:
select
sum(case when result = 'X' then 1 else 0 end) count_x,
sum(case when result is null then 1 else 0 end) count_blank
from mytable
I assume that by blank you mean null. If not, then you can change the condition in the second sum() from result is null to result = ''.
If you are running MySQL, this can be shortened a little:
select
sum(result = 'X') count_x,
sum(result is null) count_blank
from mytable

Why does this not return 0

I have a query like:
select nvl(nvl(sum(a.quantity),0)-nvl(cc.quantityCor,0),0)
from RCV_TRANSACTIONS a
LEFT JOIN (select c.shipment_line_id,c.oe_order_line_id,nvl(sum(c.quantity),0) quantityCor
from RCV_TRANSACTIONS c
where c.TRANSACTION_TYPE='CORRECT'
group by c.shipment_line_id,c.oe_order_line_id) cc on (a.shipment_line_id=cc.shipment_line_id and a.shipment_line_id=7085740)
where a.transaction_type='DELIVER'
and a.shipment_line_id=7085740
group by nvl(cc.quantityCor,0);
The query runs OK, but returns no value. I want it to return 0 if there is no quantity found. Where have I gone wrong?
An aggregation query with a GROUP BY returns no rows if all rows are filtered out.
An aggregation query with no GROUP BY always returns one row, even if all rows are filtered out.
So, just remove the GROUP BY. And change the SELECT to:
select coalesce(sum(a.quantity), 0) - coalesce(max(cc.quantityCor), 0)
I may be wrong, but it seems you merely want to subtract CORRECT quantity from DELIVER quantity for shipment 7085740. You don't need a complicated query for that. Especially your GROUP BY clauses make no sense if that is what you are after.
One way to write this query would be:
select
sum(case when transaction_type = 'DELIVER' then quantity else 0 end) -
sum(case when transaction_type = 'CORRECT' then quantity else 0 end) as diff
from rcv_transactions
where shipment_line_id = 7085740;
I had a query like this and was trying to return 'X' when the item is not valid.
SELECT case when segment1 is not null then segment1 else 'X' end
--INTO v_orgValidItem
FROM mtl_system_items_b
WHERE segment1='1676001000'--'Jul-00'--l_item
and organization_id=168;
..but it was returning NULL.
Changed to use aggregation with no group by and now it returns 'X' when the item is not valid.
SELECT case when max(segment1) is not null then max(segment1) else 'X' end valid
--INTO v_orgValidItem
FROM mtl_system_items_b
WHERE segment1='1676001000'--'Jul-00'--l_item
and organization_id=168;--l_ship_to_organization_id_pb;
Here is another example, proving the order of operations really matters.
When there is no match for this quote number, this query returns NULL:
SELECT MAX(NVL(QUOTE_VENDOR_QUOTE_NUMBER,0))
FROM PO_HEADERS_ALL
WHERE QUOTE_VENDOR_QUOTE_NUMBER='foo.bar';
..reversing the order of MAX and NVL makes all the difference. This query returns the NULL value condition:
SELECT NVL(MAX(QUOTE_VENDOR_QUOTE_NUMBER),0)
FROM PO_HEADERS_ALL
WHERE QUOTE_VENDOR_QUOTE_NUMBER='foo.bar';

sql count query with case statement

I have to execute a query from three tables avg_salary, person and emails. This simple sql query works fine.
SELECT avg_salary.id, COUNT(emails.message_from) AS email_PGA
FROM avg_salary, person, emails
WHERE person.works_in = avg_salary.id
AND person.email_address = emails.message_from
AND person.salary::numeric > avg_salary.avg
GROUP BY avg_salary.id
But I want to add another column email_PLA with the condition when
person.salary::numeric < avg_salary.avg. I can do that by joining the whole query again. But I want to use CASE in this situation. And even after trying so many times I can't get the syntax right.
I assume you need another count?
You would need something like:
SUM(CASE WHEN (person.salary::numeric < avg_salary.avg) THEN 1 ELSE 0 END) AS email_PGA
You can do conditional aggregation by using case expression and always use explicit JOIN syntax
SELECT avg_salary.id,
SUM(CASE WHEN p.salary::numeric > asal.avg THEN 1 ELSE 0 END) AS email_PGA,
SUM(CASE WHEN p.salary::numeric < asal.avg THEN 1 ELSE 0 END) AS email_PLA
FROM avg_salary asal,
INNER JOIN person p on p.works_in = asal.id
INNER JOIN emails e on e.message_from = p.email_address
--WHERE p.salary::numeric > asal.avg
GROUP BY avg_salary.id;
If you need different columns on specific conditions you have to do different SQL queries.

How to do a COUNT with a WHERE clause?

I actually have a query joining 3 tables to collect informations so I can calculate some KPIs, but my logic is flawed, here is my actual query :
SELECT t.idCustomer, t.nameCustomer
COUNT(DISTINCT t.idTrip),
SUM(
CASE
WHEN t.tripDone <> 1
THEN 1
ELSE 0
END),
SUM(CASE
WHEN t.codeIncident = 'CANCEL'
THEN 1
ELSE 0
END)
FROM
(SELECT customer.idCustomer, customer.nameCustomer, trip.tripDone, incident.codeIncident
FROM CUSTOMER customer
JOIN TRIP trip ON customer.idCustomer = trip.idCustomer
JOIN INCIDENT incident ON trip.idTrip = incident.idTrip) t
GROUP BY t.idCustomer, t.nameCustomer
So, I want to know for each Customer :
COUNT(DISTINCT t.idTrip) -> The number of trips by this customer
Sum when t.tripDone <> 1 -> The number of trips that are done by this customer ( not ingoing )
Sum when t.codeIncident = 'CANCEL' -> The number of trips by this customer where there was a cancellation.
The big mistake I made here, is that a trip can have multiple codeIncidents (example : one record for an idTrip with the codeIncident 'CANCEL' and another record with same idTrip with the codeIncident 'DELAYED'), so when I calculate the Sum when t.tripDone <> 1 I get a result of : '2' instead of '1' (because there are 2 records in my from Clause that have the t.tripDone <> 1 for the same idTrip).
Would you have any idea on how I should process this query so I can do the Sum when tripDone <> 1 only once for each tripId ?
Thanks a lot for the help !
If you need some more infos I'm available, and sorry for my lack of english skills !
It sounds like you want to do the same count(distinct ...) pattern for the columns you're currently summing, but with some logic. You can use case within a count instead in the same way:
...
COUNT(
DISTINCT CASE
WHEN t.tripDone <> 1
THEN t.idTrip
ELSE null
END),
COUNT(
DISTINCT CASE
WHEN t.codeIncident = 'CANCEL'
THEN t.idTrip
ELSE null
END)
The else null is a bit redundant as that's the default. As count() ignores nulls, if the when isn't matched then that trip ID isn't counted.
First Select idTrip field in your inner query that means table "t"

SQL Nested Select statements with COUNT()

I'll try to describe as best I can, but it's hard for me to wrap my whole head around this problem let alone describe it....
I am trying to select multiple results in one query to display the current status of a database. I have the first column as one type of record, and the second column as a sub-category of the first column. The subcategory is then linked to more records underneath that, distinguished by status, forming several more columns. I need to display every main-category/subcategory combination, and then the count of how many of each sub-status there are beneath that subcategory in the subsequent columns. I've got it so that I can display the unique combinations, but I'm not sure how to nest the select statements so that I can select the count of a completely different table from the main query. My problem lies in that to display the main category and sub category, I can pull from one table, but I need to count from a different table. Any ideas on the matter would be greatly appreciated
Here's what I have. The count statements would be replaced with the count of each status:
SELECT wave_num "WAVE NUMBER",
int_tasktype "INT / TaskType",
COUNT (1) total,
COUNT (1) "LOCKED/DISABLED",
COUNT (1) released,
COUNT (1) "PARTIALLY ASSEMBLED",
COUNT (1) assembled
FROM (SELECT DISTINCT
(t.invn_need_type || ' / ' || s.code_desc) int_tasktype,
t.task_genrtn_ref_nbr wave_num
FROM sys_code s, task_hdr t
WHERE t.task_genrtn_ref_nbr IN
(SELECT ship_wave_nbr
FROM ship_wave_parm
WHERE TRUNC (create_date_time) LIKE SYSDATE - 7)
AND s.code_type = '590'
AND s.rec_type = 'S'
AND s.code_id = t.task_type),
ship_wave_parm swp
GROUP BY wave_num, int_tasktype
ORDER BY wave_num
Image here: http://i.imgur.com/JX334.png
Guessing a bit,both regarding your problem and Oracle (which I've - unfortunately - never used), hopefully it will give you some ideas. Sorry for completely messing up the way you write SQL, SELECT ... FROM (SELECT ... WHERE ... IN (SELECT ...)) simply confuses me, so I have to restructure:
with tmp(int_tasktype, wave_num) as
(select distinct (t.invn_need_type || ' / ' || s.code_desc), t.task_genrtn_ref_nbr
from sys_code s
join task_hdr t
on s.code_id = t.task_type
where s.code_type = '590'
and s.rec_type = 'S'
and exists(select 1 from ship_wave_parm p
where t.task_genrtn_ref_nbr = p.ship_wave_nbr
and trunc(p.create_date_time) = sysdate - 7))
select t.wave_num "WAVE NUMBER", t.int_tasktype "INT / TaskType",
count(*) TOTAL,
sum(case when sst.sub_status = 'LOCKED' then 1 end) "LOCKED/DISABLED",
sum(case when sst.sub_status = 'RELEASED' then 1 end) RELEASED,
sum(case when sst.sub_status = 'PARTIAL' then 1 end) "PARTIALLY ASSEMBLED",
sum(case when sst.sub_status = 'ASSEMBLED' then 1 end) ASSEMBLED
from tmp t
join sub_status_table sst
on t.wave_num = sst.wave_num
group by t.wave_num, t.int_tasktype
order by t.wave_num
As you notice, I don't know anything about the table with the substatuses.
You can use inner join, grouping and count to get your result:
suppose tables are as follow :
cat (1)--->(n) subcat (1)----->(n) subcat_detail.
so the query would be :
select cat.title cat_title ,subcat.title subcat_title ,count(*) as cnt from
cat inner join sub_cat on cat.id=subcat.cat_id
inner join subcat_detail on subcat.ID=am.subcat_detail_id
group by cat.title,subcat.title
Generally when you need different counts, you need to use the CASE statment.
select count(*) as total
, case when field1 = "test' then 1 else 0 end as testcount
, case when field2 = 'yes' then 1 else 0 endas field2count
FROM table1