SQL get count from one table and split to two columns - sql

I have a table like this:
Date Product
1/1/2015 Apples
1/1/2015 Apples
1/1/2015 Oranges
1/2/2015 Apples
1/2/2015 Apples
1/2/2015 Oranges
How can I do a select so I get something like this:
Date Count of Apples Count of Oranges
1/1/2015 2 1
1/2/2015 2 1
Thanks. I have tried case like this but the error is being thrown:
Select 'Date',
CASE WHEN 'Product' = 'Apples' THEN COUNT(*) ELSE 0 END as 'Count'
FROM #TEMP Group by 1,2
Each GROUP BY expression must contain at least one column that is not an outer reference.

You can do conditional aggregation like this:
select
[date],
sum(case when Product = 'Apples' then 1 else 0 end) as [Count of Apples],
sum(case when Product = 'Oranges' then 1 else 0 end) as [Count of Oranges]
from #temp
group by [date]

With conditional aggregation:
select date,
sum(case when Product = 'Apples' then 1 else 0 end) as Apples,
sum(case when Product = 'Oranges' then 1 else 0 end) as Oranges,
from table
group by date

SQL Server does not accept column references in the GROUP BY. So, "1" and "2" refer to, well, the numbers one and two.
However, you seem to be confusing string constants and columns. Only use single quotes for string and date constants. I suspect that Date and Product are the names of columns. So, the query you probably want is a conditional aggregation:
Select Date,
SUM(CASE WHEN Product = 'Apples' THEN 1 ELSE 0 END) as NumApples
FROM #TEMP
Group by Date
Order by Date;

Related

Filter results within groups sql

In the table below, I want to know how many customers ordered lunch without a coffee. The result would be 1, for sale ID 300, because two lunches were ordered but only one coffee.
It’s been 8 years since I last used SQL! How do I say “group the records by sale ID and for each group, drop groups where there is no lunch or COUNT(coffee) < COUNT(lunch)"?
SALE ID
Product
100
coffee
100
lunch
200
coffee
300
lunch
300
lunch
300
coffee
here is one way:
select count(*) from (
select saleID
from tablename
group by saleID
having sum(case when product ='coffee' then 1 else 0 end) = 0
and sum(case when product ='lunch' then 1 else 0 end) = 1
) t
You can do it with aggregation and the conditions in the HAVING clause.
This query:
SELECT sale_id
FROM tablename
GROUP BY sale_id
HAVING SUM(product = 'lunch') > SUM(product = 'coffee');
returns all the sale_ids that you want.
This query:
SELECT DISTINCT COUNT(*) OVER () counter
FROM tablename
GROUP BY sale_id
HAVING SUM(product = 'lunch') > SUM(product = 'coffee');
returns the number of sale_ids that you want.
See the demo.
select count(*) from (
--in this subquery calculate counts and ignore items that haven't any lunch
select
saleID, sum(case when product ='coffee' then 1 else 0 end) as coffee,
sum(case when product ='lunch' then 1 else 0 end) lunch
from tablename
group by saleID
having sum(case when product ='lunch' then 1 else 0 end) >= 1 --Here we are ignoring all items haven't any lunch
) t
where lunch > coffee -- we check second condition be ok

2 column with 2 different condition in one table

is it possible to create a query that will output 2 column with 2 different WHERE clause
this my ideal output:
| YEAR | WW | COUNT | *COUNT2 |
where count 1 is the result of the 1st WHERE clause. Which I already created.
What I want is to have another column where in the value will be with different WHERE clause.
here's my query:
SELECT extract(YEAR FROM EVT_TARGET) as Years, to_char(EVT_TARGET, 'ww') AS WorkWeek, COUNT(*)
FROM r5events
WHERE EVT_JOBTYPE = 'CORR' AND EVT_RSTATUS <> 'C' AND EVT_TARGET IS NOT NULL
GROUP BY extract(YEAR FROM EVT_TARGET), to_char(EVT_TARGET, 'ww');
with this query I was able to get the 1st 3 column, my problem now is how to supply value on the 4th column with the value of EVT_RSTATUS = 'C'.
Any insight?
TIA
I think you want conditional aggregation:
SELECT
extract(YEAR FROM EVT_TARGET) as Years,
to_char(EVT_TARGET,'ww') AS WorkWeek,
SUM(CASE WHEN EVT_RSTATUS <> 'C' THEN 1 ELSE 0 END) AS cnt1,
SUM(CASE WHEN EVT_RSTATUS = 'C' THEN 1 ELSE 0 END) AS cnt2
FROM r5events
WHERE EVT_JOBTYPE ='CORR' AND EVT_TARGET IS NOT NULL
GROUP BY extract(YEAR FROM EVT_TARGET), to_char(EVT_TARGET,'ww');

SQL: Multiple select that differ by only one condition

I've got a beginner question. My SQL table looks like:
| Date | Type | Manufacturer |
2016/04/01 A X
2016/04/01 B Y
2016/04/02 B X
2016/05/07 A Z
... ... ...
My aim is to count the quantity of "Types" by manufacturers between two dates. I would like to get a result like following:
| Manufacturer | Quantity_TypeA | Quantity_TypeB |
X 1 1
Y 0 1
Z 1 0
My query looks like:
select Manufacturer as Manufacturer,
COUNT(*) as Quantity_TypeA
From MyTable
Where [Type] = 'A' and
Date between '20150101' and '20160930',
COUNT(*) as Quantity_TypeB
From MyTable
Where [Type] = 'B' and
Date between '20150101' and '20160930'
group by Manufacturer Order by Quantity_TypeA DESC
I have also tried to use functions like CASE on the Type and it didn't work. I am missing something but what?
Try this
select Manufacturer as Manufacturer,
SUM(case when [Type] = 'A' then 1 else 0 end) as Quantity_TypeA,
SUM(case when [Type] = 'B' then 1 else 0 end) as Quantity_TypeB
From MyTable
Where
Date between '20150101' and '20160930'
group by Manufacturer
Use case expressions to do conditional counting:
select Manufacturer as Manufacturer,
COUNT(case when [Type] = 'A' then 1 end) as Quantity_TypeA,
COUNT(case when [Type] = 'B' then 1 end) as Quantity_TypeB
from MyTable
where Date between '20150101' and '20160930',
group by Manufacturer
order by Quantity_TypeA DESC
count() does only count non-null values. The case expressions either return 1 or null, i.e. only A's or B's are counted.

SQL count of values from different columns

I've got a Dog table. Each dog has Breed and can have 0 to 2 photos. I need to recieve count of photos of all dogs for each breed: table with BreedId and matching PhotosCount. So result table should be:
BreedID|PhotosCount
-------------------
1 |3
-------------------
2 |1
-------------------
This should do the trick:
SELECT BreedID AS B, COUNT(Photo1) + COUNT(Photo2) AS C
FROM Dog
GROUP BY BreedID
COUNT aggregate function simply doesn't take into consideration NULL values. If, for a specific BreedID, all values of either Photo1 or Photo2 are NULL, then COUNT returns 0.
This should work in single scan:
SELECT
BreedID,
SUM(CASE WHEN Photo1 IS NOT NULL THEN 1 ELSE 0 END)
+ SUM(CASE WHEN Photo2 IS NOT NULL THEN 1 ELSE 0 END) [Count]
FROM Table
GROUP BY BreedID
Use Group By and SUM Of Photo1 and Photo2:
Note: If you wants the output for each dog you have to include DogId in group clause.
;WITH T AS
(
SELECT
BreedId,
SUM (CASE ISNULL(Photo1,0) WHEN 1 THEN 1 ELSE 0 END) AS Photo1,
SUM (CASE ISNULL(Photo2,0) WHEN 1 THEN 1 ELSE 0 END) AS Photo2
FROM TableName
Group By BreedId
)
SELECT
BreedId,
SUM(Photo1+Photo2) AS TotalPhoto
FROM T
Or Simply
SELECT
BreedId,
SUM (CASE ISNULL(Photo1,0) WHEN 1 THEN 1 ELSE 0 END + CASE ISNULL(Photo2,0) WHEN 1 THEN 1 ELSE 0 END) AS TotalPhoto
FROM TableName
Group By BreedId
SELECT BreedID AS Breed, COUNT(Photo1) + COUNT(Photo2) AS #ofPhotos
FROM Dog
GROUP BY BreedID;

Using distinct and case for two separate columns

I am counting cases by year using the following code:
COUNT(CASE WHEN Year(FilingDate)=2008 THEN 1 ELSE NULL END) AS '2008'
and I want to only count these cases when another column is distinct. The other column is called 'FilingDate' What I imagine would look something like this:
COUNT(CASE distinct (DocketNumber) WHEN Year(FilingDate)=2008 THEN 1 ELSE NULL END) AS '2008',
The Sample Records:
DocketNumber FilingDate
123 2008
123 2008
123 2008
111 2009
112 2009
I would just like to recieve = 1
Any Ideas?
Thanks
Use option with SUBQUERY and GROUP BY clause
SELECT COUNT(CASE WHEN YearFilingDate = 2008 THEN 1 END) AS '2008'
FROM
(
SELECT Year(FilingDate) AS YearFilingDate, DocketNumber
FROM dbo.test55
GROUP BY Year(FilingDate), DocketNumber
) x
Demo on SQLFiddle
SELECT COUNT(CASE WHEN Year(FilingDate)=2008 THEN 1 ELSE NULL END) AS '2008'
GROUP BY DocketNumber
may be.