This question already has answers here:
How can I get multiple counts with one SQL query?
(12 answers)
Closed 4 years ago.
I am counting specific things in a SQL Server table. I am using multiple count queries, but I am wondering if it's possible to combine them into a single query with the column name and count numbers in a single table for display.
My queries are:
select count(*) as Ask_Count
from Pld_OpenSalesOrdersLines
where left(C_Item_ID, 1) = '*'
select count(*) as M_Count
from Pld_OpenSalesOrdersLines
where (left(C_Item_ID, 1) = 'M' and len(C_Item_ID) = 1)
select count(*) as MN_Count
from Pld_OpenSalesOrdersLines
where (left(C_Item_ID, 2) = 'MN' and len(C_Item_ID) = 2)
I tried a couple stupid things to combine them, but they were a failure. I honestly can't even begin to think how to combine them, maybe it's not possible?
Thanks!
You could use CASE expression to perform conditional aggregation:
select
COUNT(CASE WHEN LEFT(C_Item_ID,1)='*' THEN 1 END) AS Ask_Count,
COUNT(CASE WHEN LEFT(C_Item_ID,1)='M' AND LEN(C_Item_ID)=1 THEN 1 END) M_Count,
COUNT(CASE WHEN LEFT(C_Item_ID,2)='MN' AND LEN(C_Item_ID)=2 THEN 1 END) MN_Count
from Pld_OpenSalesOrdersLines
Use conditional aggregation:
select sum(case when LEFT(C_Item_ID,1) = '*' then 1 else 0 end) as count_1,
sum(case when LEFT(C_Item_ID,1) = 'M' AND LEN(C_Item_ID)=1 then 1 else 0 end) as count_2,
sum(case when LEFT(C_Item_ID,2) = 'MN' AND LEN(C_Item_ID)=2 then 1 else 0 end) as count_3
from Pld_OpenSalesOrdersLines;
I would write the logic like this, though:
select sum(case when C_Item_ID like '*%' then 1 else 0 end) as count_1,
sum(case when C_Item_ID = 'M' then 1 else 0 end) as count_2,
sum(case when C_Item_ID = 'MN' then 1 else 0 end) as count_3
from Pld_OpenSalesOrdersLines;
Doing a left() on a column and then checking the length is redundant. Just use =.
Related
This question already has answers here:
Conditional Count on a field
(8 answers)
Closed last year.
I'm working with SQL Server and I want to create a view (my_View) which has these columns :
[element_1]
[element_2]
[element_3]
[element_4]
All of them are referring to the same column, named [parent_1], in another table (AT)
[parent_1] can have 4 possible values [value_1], [value_2], [value_3] and [value_4].
What I want is that, using COUNT,
[element_1] is equal to the number of times that [parent_1] is equal to [value_1]
same for [element_2], [element_3] and [element_4] equals to [value_2], [value_3] and [value_4].
Is it possible to use "==" inside the COUNT to see if it checks the criteria?
Something like this:
COUNT (AT.parent_1 == "value_1") AS element_1
COUNT (AT.parent_1 == "value_2") AS element_2
COUNT (AT.parent_1 == "value_3") AS element_3
COUNT (AT.parent_1 == "value_4") AS element_4
Thanks guys
You can use the CASE instruction for that
https://learn.microsoft.com/fr-fr/sql/t-sql/language-elements/case-transact-sql?view=sql-server-ver15
SUM (CASE WHEN AT.parent_1 = 'value_4' THEN 1 ELSE 0 END) as element_4
You can do something like:
SELECT
sum(case when parent_1 = "value_1" then 1 else 0 end) as element_1,
sum(case when parent_1 = "value_2" then 1 else 0 end) as element_2,
sum(case when parent_1 = "value_3" then 1 else 0 end) as element_3,
sum(case when parent_1 = "value_4" then 1 else 0 end) as element_4
FROM table;
create my_view as
select
-- other list of columns,
SUM (CASE WHEN AT.parent_1 = 'value_1' THEN 1 ELSE 0 END) as element_1,
SUM (CASE WHEN AT.parent_1 = 'value_2' THEN 1 ELSE 0 END) as element_2,
SUM (CASE WHEN AT.parent_1 = 'value_3' THEN 1 ELSE 0 END) as element_3,
SUM (CASE WHEN AT.parent_1 = 'value_4' THEN 1 ELSE 0 END) as element_4
from tableName AT
There is no need to use == like that of a programming language, in SQL comparison operator is =
I need help How can I merge the column into a single column, here is my code, is this method is correct. I want to get the count of the selected row in the table for the columns.
SELECT
CAT_MGR,
SUM ( case when CAT_MGR = 'A' THEN 1 else 0 end ) AS DESIGN,
sum (case when CAT_MGR = 'b' THEN 1 else 0 END) AS DESIGN,
sum (case when CAT_MGR = 'c' THEN 1 else 0 END) AS DESIGN
from Table_A
GROUP BY
CAT_MGR
Can you guys help me I'm a beginner at SQL.
Thank you in advance
If you want just one row in the resultset, then remove the group by clause. Then, if you want to count the three cat mgr together, you can use in:
select
sum(case when cat_mgr = 'a' then 1 else 0 end ) as design_a,
sum(case when cat_mgr = 'b' then 1 else 0 end ) as design_b,
sum(case when cat_mgr = 'c' then 1 else 0 end ) as design_c,
sum(case when cat_mgr in ('a', 'b', 'c') then 1 else 0 end ) as design
from Table_a
You just need to make addion like below in order to get one column "Design"
SELECT
CAT_MGR,
SUM (case when CAT_MGR = 'A' THEN 1 else 0 end )
+ sum (case when CAT_MGR = 'b' THEN 1 else 0 END)
+ sum (case when CAT_MGR = 'c' THEN 1 else 0 END)
AS DESIGN
from TJD_CORE_CATPB_TB
GROUP BY
CAT_MGR
I have an access to Oracle server. There is a table on the Oracle server called Transactions which contains the following data:
I don't known the number of values, so we need to implement dynamic sql in Oracle.
I need to pivot that data so the results are:
Any suggestions?
You can use conditional aggregation:
select subno,
sum(case when offer = 'offer1' then 1 else 0 end) as offer1,
sum(case when offer = 'offer2' then 1 else 0 end) as offer2,
sum(case when offer = 'offer3' then 1 else 0 end) as offer3
from t
group by subno;
This question already has an answer here:
How to use an Alias in a Calculation for Another Field
(1 answer)
Closed 3 years ago.
In my query below I am counting occurrences in a table based on the Status column. I also want to perform calculations based on the counts I am returning. For example, let's say I want to add 100 to the Snoozed value... how do I do this? Below is what I thought would do it:
SELECT
pu.ID Id, pu.Name Name,
COUNT(*) LeadCount,
SUM(CASE WHEN Status = 'Working' THEN 1 ELSE 0 END) AS Working,
SUM(CASE WHEN Status = 'Uninterested' THEN 1 ELSE 0 END) AS Uninterested,
SUM(CASE WHEN Status = 'Converted' THEN 1 ELSE 0 END) AS Converted,
SUM(CASE WHEN SnoozedId > 0 THEN 1 ELSE 0 END) AS Snoozed,
Snoozed + 100 AS Test
FROM
Prospects p
INNER JOIN
ProspectsUsers pu on p.OwnerId = pu.SalesForceId
WHERE
p.Store = '108'
GROUP BY
pu.Name, pu.Id
ORDER BY
Name
I get this error:
Invalid column name 'Snoozed'.
How can I take the value of the previous SUM statement, add 100 to it, and return it as another column? What I was aiming for is an additional column labeled Test that has the Snooze count + 100.
You can't use one column to create another column in the same way that you are attempting. You have 2 options:
Do the full calculation (as #forpas has mentioned in the comments above)
Use a temp table or table variable to store the data, this way you can get the first 5 columns, and then you can add the last column or you can select from the temp table and do the last column calculations from there.
You can not use an alias as a column reference in the same query. The correct script is:
SELECT
pu.ID Id, pu.Name Name,
COUNT(*) LeadCount,
SUM(CASE WHEN Status = 'Working' THEN 1 ELSE 0 END) AS Working,
SUM(CASE WHEN Status = 'Uninterested' THEN 1 ELSE 0 END) AS Uninterested,
SUM(CASE WHEN Status = 'Converted' THEN 1 ELSE 0 END) AS Converted,
SUM(CASE WHEN SnoozedId > 0 THEN 1 ELSE 0 END)+100 AS Snoozed
FROM
Prospects p
INNER JOIN
ProspectsUsers pu on p.OwnerId = pu.SalesForceId
WHERE
p.Store = '108'
GROUP BY
pu.Name, pu.Id
ORDER BY
Name
MSSQL does not allow you to reference fields (or aliases) in the SELECT statement from within the same SELECT statement.
To work around this:
Use a CTE. Define the columns you want to select from in the CTE, and then select from them outside the CTE.
;WITH OurCte AS (
SELECT
5 + 5 - 3 AS OurInitialValue
)
SELECT
OurInitialValue / 2 AS OurFinalValue
FROM OurCte
Use a temp table. This is very similar in functionality to using a CTE, however, it does have different performance implications.
SELECT
5 + 5 - 3 AS OurInitialValue
INTO #OurTempTable
SELECT
OurInitialValue / 2 AS OurFinalValue
FROM #OurTempTable
Use a subquery. This tends to be more difficult to read than the above. I'm not certain what the advantage is to this - maybe someone in the comments can enlighten me.
SELECT
5 + 5 - 3 AS OurInitialValue
FROM (
SELECT
OurInitialValue / 2 AS OurFinalValue
) OurSubquery
Embed your calculations. opinion warning This is really sloppy, and not a great approach as you end up having to duplicate code, and can easily throw columns out-of-sync if you update the calculation in one location and not the other.
SELECT
5 + 5 - 3 AS OurInitialValue
, (5 + 5 - 3) / 2 AS OurFinalValue
You can't use a column alias in the same select. The column alias do not precedence / sequence; they are all created after the eval of the select result, just before group by and order by.
You must repeat code :
SELECT
pu.ID Id,pu.Name Name,
COUNT(*) LeadCount,
SUM(CASE WHEN Status = 'Working' THEN 1 ELSE 0 END) AS Working,
SUM(CASE WHEN Status = 'Uninterested' THEN 1 ELSE 0 END) AS Uninterested,
SUM(CASE WHEN Status = 'Converted' THEN 1 ELSE 0 END) AS Converted,
SUM(CASE WHEN SnoozedId > 0 THEN 1 ELSE 0 END) AS Snoozed,
SUM(CASE WHEN SnoozedId > 0 THEN 1 ELSE 0 END)+ 100 AS Test
FROM
Prospects p
INNER JOIN
ProspectsUsers pu on p.OwnerId = pu.SalesForceId
WHERE
p.Store = '108'
GROUP BY
pu.Name, pu.Id
ORDER BY
Name
If you don't want to repeat the code, use a subquery
SELECT
ID, Name, LeadCount, Working, Uninterested,Converted, Snoozed, Snoozed +100 AS test
FROM
(SELECT
pu.ID Id,pu.Name Name,
COUNT(*) LeadCount,
SUM(CASE WHEN Status = 'Working' THEN 1 ELSE 0 END) AS Working,
SUM(CASE WHEN Status = 'Uninterested' THEN 1 ELSE 0 END) AS Uninterested,
SUM(CASE WHEN Status = 'Converted' THEN 1 ELSE 0 END) AS Converted,
SUM(CASE WHEN SnoozedId > 0 THEN 1 ELSE 0 END) AS Snoozed
FROM Prospects p
INNER JOIN ProspectsUsers pu on p.OwnerId = pu.SalesForceId
WHERE p.Store = '108'
GROUP BY pu.Name, pu.Id) t
ORDER BY Name
or a view
I am having trouble formulating a query to get the desired output.
This query involves one table and two columns.
First column bld_stat has 4 different values Private, public, Public-Abandoned, Private-Abandoned the other column bld_type, single_flr, multi_flr, trailer, Whs.
I need to get results that look like this:
So far I can get the first two columns but after that I have not been able to logically get a query to work
SELECT bld_stat, COUNT(grade) AS single_flr
FROM (SELECT bld_stat,bld_type
FROM bld_inventory WHERE bld_type = 'single_flr') AS grade
GROUP BY bld_stat,bld_type,grade
The term you are going for is pivoting. I think this should work...no need for the subquery, and I've changed your group by to only bld_stat
SELECT bld_stat,
sum(case when bld_type = 'singl_flr' then 1 else 0 end) AS single_flr,
sum(case when bld_type = 'multi_flr' then 1 else 0 end) AS multi_flr,
sum(case when bld_type = 'trailer' then 1 else 0 end) AS trailer,
sum(case when bld_type = 'whs' then 1 else 0 end) AS WHS
FROM bld_inventory
GROUP BY bld_stat