How to count values in SQLITE in more then one column? - sql

I like to count the number of appearance of my users in more then one column. This is how I count the values in columns:
SELECT COUNT(col_01) FROM table_01 WHERE col_01 = 'John' // result: 2
SELECT COUNT(col_02) FROM table_01 WHERE col_02 = 'John' // result: 4
Is there any way to count John in one step in all columns I have and get the results 6?
Thank you in advance!

First filter the table so that you get only the rows with 'John' in any of the 2 columns and then use aggregate function TOTAL() on each column:
SELECT TOTAL(col_01 = 'John') + TOTAL(col_02 = 'John') AS total
FROM table_01
WHERE 'John' IN (col_01, col_02);

Try conditional aggregation
select
sum(case when col_01='John' then 1 end) +
sum(case when col_02='John' then 1 end)
from table_01;

Related

Find records only all value are same in column otherwise return 0

I have the following table
id
name
1
Gaurav
1
Ram
1
Gaurav
1
Gaurav
From the above table I want to fetch records if name have same value as Gaurav. For example one row has name Ram so it should not return any thing. If all value is Gaurav then return id.
On MySQL, you could use aggregation:
SELECT id
FROM yourTable
GROUP BY id
HAVING SUM(name = 'Gaurav') = COUNT(*);
On all databases:
SELECT id
FROM yourTable
GROUP BY id
HAVING COUNT(CASE WHEN name = 'Gaurav' THEN 1 END) = COUNT(*);
You can try this as well. Bit hardcoded. You can use 0 instead of null and remove where clause as well if you want.
SELECT Case When Name ='Gaurav' Then ID else NULL END AS ID
FROM Yourtable
where name ='Gaurav'

check and compare the count from two tables without relation

I have below tables
Table1: "Demo"
Columns: SSN, sales, Create_DT,Update_Dt
Table2: "Agent"
Columns: SSN,sales, Agent_Name, Create_Dt, Update_DT
Scenario 1 and desired result set:
I want output as 0 if the count of SSN in Demo table is matched with the count of SSN in Agent table
if the count is not matched then I want result as 1
Scenario 2 and desired result set:
I want output as 0 if the sum of sales in Demo table is matched with the sum of sales in Agent table
if the sum is not matched then I want result as 1
Please help on this query part
Thanks
You can write two queries separately to take counts within the result query
SELECT (SELECT count(Demo.SSN) as SSN1 from Demo)!=(SELECT count(Agent.SSN) as SSN2 from Agent) AS Result;
Basically what the inner queries does is it checked whether the counts are equal or not and outputs 1 if it is true and 0 if it is false. Since you have asked to output 1 if it is false I used '!=' sign.
You can try the same procedure in scenario 2 also
For scenario 1
select (Case when (select count(ssn) from Demo)=(select count(ssn) from Agent) then 0 else 1 end) as desired_result
If you want to count unique ssn then:
select (Case when (select count(distinct ssn) from Demo)=(select count(distinct ssn) from Agent) then 0 else 1 end) as desired_result
For scenario 2:
select (Case when (select sum(sales) from Demo)=(select sum(sales) from Agent) then 0 else 1 end) as desired_result
I would suggest one query with both sets of information:
select (d.num_ssn <> a.num_ssn) as have_different_ssn_count,
(d.sales <> a.sales) as have_different_sales
from (select count(distinct ssn) as num_ssn,
coalesce(sum(sales), 0) as sales
from demo
) d cross join
(select count(distinct ssn) as num_ssn,
coalesce(sum(sales), 0) as sales
from agent
) a;
Note: This returns boolean values -- true/false rather than 1/0. If you really want 0/1, then use case:
select (case when d.num_ssn <> a.num_ssn then 1 else 0 end) as have_different_ssn_count,
(case when d.sales <> a.sales then 1 else 0 end) as have_different_sales
It would not surprise me if you were not only interested in the total counts but also that the agent/sales combinations are the same in both tables. If that is the case, please ask a new question with a clear explanation. Sample data and desired results help.

SQL, return select results with different where clauses

I have table whose column is just the length of a session and I would like to return the number of session that have zero length and the number of sessions that have length greater than zero.
I can do that with two separate commands
select count(session_length) from my_table where session_length=0
select count(session_length) from my_table where session_length>0
But I would like to see the results combined in one table
You can do it with one query using conditional aggregation.
select
count(case when session_length = 0 then 1 end),
count(case when session_length > 0 then 1 end)
from my_table
select 1 as QryNo, count(session_length) as SessLen
from my_table
where session_length=0
union
select 2 as QryNo, count(session_length) as SessLen
from my_table
where session_length>0
or
select
case
when session_length = 0 then 1
else 2
end as QryNo,
count(session_length) as SessLen
from my_table
This may be too simple so apologies if I have misread your query but Can you use
select count(session_length) from my_table where session_length >= 0
Again, Apologies if this is not what you're looking for.

Select Distinct Attribute and Print out Count of another even when the count is 0

I don't quite know how I should describe the problem for title, but here's my question.
I have a table named hello with two columns named time and state.
Time | State
Here's an example of the data I have
1 DC
1 VA
1 VA
2 DC
2 MD
3 MD
3 MD
3 VA
3 DC
I would like to get all the possible time and the count of "VA" (0 if "VA" doesn't appear at the time)
The output would look like this
Time Number
1 2
2 0
3 1
I tried to do
SELECT DISTINCT time,
COUNT(state) as Number
FROM hello
WHERE state = 'VA'
GROUP BY time
but it doesn't seem to work.
This is a conditional aggregation:
select time, sum(case when state = 'VA' then 1 else 0 end) as NumVA
from hello
group by time
I want to add that you should never use distinct when you have a group by. The two are redundant. Distinct as a keyword is not even needed in the SQL language; semantically, it is just shorthand for grouping by all the columns.
SELECT TIME,
SUM(CASE WHEN State = 'VA' THEN 1 ELSE 0 END)
FROm tableName
GROUP BY Time
SQLFiddle Demo
One rule of thumb is to get your counts first and put them into a temp for use later.
See below:
Create table temp(Num int, [state] varchar(2))
Insert into temp(Num,[state])
Select 1,'DC'
UNION ALL
Select 1,'VA'
UNION ALL
Select 1,'VA'
UNION ALL
Select 2,'DC'
UNION ALL
Select 2,'MD'
UNION ALL
Select 3,'MD'
UNION All
Select 3,'MD'
UNION ALL
Select 3,'VA'
UNION ALL
Select 3,'DC'
Select t.Num [Time],t.[State]
, CASE WHEN t.[state] = 'VA' THEN Count(t.[State]) ELSE 0 END [Number]
INTO #temp2
From temp t
Group by t.Num, t.[state]
--drop table #temp2
Select
t2.[time]
,SUM(t2.[Number])
From #temp2 t2
group by t2.[time]

Is it possible to specify condition in Count()?

Is it possible to specify a condition in Count()? I would like to count only the rows that have, for example, "Manager" in the Position column.
I want to do it in the count statement, not using WHERE; I'm asking about it because I need to count both Managers and Other in the same SELECT (something like Count(Position = Manager), Count(Position = Other)) so WHERE is no use for me in this example.
If you can't just limit the query itself with a where clause, you can use the fact that the count aggregate only counts the non-null values:
select count(case Position when 'Manager' then 1 else null end)
from ...
You can also use the sum aggregate in a similar way:
select sum(case Position when 'Manager' then 1 else 0 end)
from ...
Assuming you do not want to restrict the rows that are returned because you are aggregating other values as well, you can do it like this:
select count(case when Position = 'Manager' then 1 else null end) as ManagerCount
from ...
Let's say within the same column you had values of Manager, Supervisor, and Team Lead, you could get the counts of each like this:
select count(case when Position = 'Manager' then 1 else null end) as ManagerCount,
count(case when Position = 'Supervisor' then 1 else null end) as SupervisorCount,
count(case when Position = 'Team Lead' then 1 else null end) as TeamLeadCount,
from ...
#Guffa 's answer is excellent, just point out that maybe is cleaner with an IF statement
select count(IIF(Position = 'Manager', 1, NULL)) as ManagerCount
from ...
Depends what you mean, but the other interpretation of the meaning is where you want to count rows with a certain value, but don't want to restrict the SELECT to JUST those rows...
You'd do it using SUM() with a clause in, like this instead of using COUNT():
e.g.
SELECT SUM(CASE WHEN Position = 'Manager' THEN 1 ELSE 0 END) AS ManagerCount,
SUM(CASE WHEN Position = 'CEO' THEN 1 ELSE 0 END) AS CEOCount
FROM SomeTable
If using Postgres or SQLite, you can use the Filter clause to improve readability:
SELECT
COUNT(1) FILTER (WHERE POSITION = 'Manager') AS ManagerCount,
COUNT(1) FILTER (WHERE POSITION = 'Other') AS OtherCount
FROM ...
BigQuery also has Countif - see the support across different SQL dialects for these features here:
https://modern-sql.com/feature/filter
You can also use the Pivot Keyword if you are using SQL 2005 or above
more info and from Technet
SELECT *
FROM #Users
PIVOT (
COUNT(Position)
FOR Position
IN (Manager, CEO, Employee)
) as p
Test Data Set
DECLARE #Users TABLE (Position VARCHAR(10))
INSERT INTO #Users (Position) VALUES('Manager')
INSERT INTO #Users (Position) VALUES('Manager')
INSERT INTO #Users (Position) VALUES('Manager')
INSERT INTO #Users (Position) VALUES('CEO')
INSERT INTO #Users (Position) VALUES('Employee')
INSERT INTO #Users (Position) VALUES('Employee')
INSERT INTO #Users (Position) VALUES('Employee')
INSERT INTO #Users (Position) VALUES('Employee')
INSERT INTO #Users (Position) VALUES('Employee')
INSERT INTO #Users (Position) VALUES('Employee')
Do you mean just this:
SELECT Count(*) FROM YourTable WHERE Position = 'Manager'
If so, then yup that works!
I know this is really old, but I like the NULLIF trick for such scenarios, and I found no downsides so far. Just see my copy&pasteable example, which is not very practical though, but demonstrates how to use it.
NULLIF might give you a small negative impact on performance, but I guess it should still be faster than subqueries.
DECLARE #tbl TABLE ( id [int] NOT NULL, field [varchar](50) NOT NULL)
INSERT INTO #tbl (id, field)
SELECT 1, 'Manager'
UNION SELECT 2, 'Manager'
UNION SELECT 3, 'Customer'
UNION SELECT 4, 'Boss'
UNION SELECT 5, 'Intern'
UNION SELECT 6, 'Customer'
UNION SELECT 7, 'Customer'
UNION SELECT 8, 'Wife'
UNION SELECT 9, 'Son'
SELECT * FROM #tbl
SELECT
COUNT(1) AS [total]
,COUNT(1) - COUNT(NULLIF([field], 'Manager')) AS [Managers]
,COUNT(NULLIF([field], 'Manager')) AS [NotManagers]
,(COUNT(1) - COUNT(NULLIF([field], 'Wife'))) + (COUNT(1) - COUNT(NULLIF([field], 'Son'))) AS [Family]
FROM #tbl
Comments appreciated :-)
Here is what I did to get a data set that included both the total and the number that met the criteria, within each shipping container. That let me answer the question "How many shipping containers have more than X% items over size 51"
select
Schedule,
PackageNum,
COUNT (UniqueID) as Total,
SUM (
case
when
Size > 51
then
1
else
0
end
) as NumOverSize
from
Inventory
where
customer like '%PEPSI%'
group by
Schedule, PackageNum
Note with PrestoDB SQL (from Facebook), there is a shortcut:
https://prestodb.io/docs/current/functions/aggregate.html
count_if(x) → bigint
Returns the number of TRUE input values. This
function is equivalent to count(CASE WHEN x THEN 1 END)
SELECT COUNT(*) FROM bla WHERE Position = 'Manager'
In MySQL, boolean expressions evaluate to 0 or 1, so the following aggregation works:
select sum(Position = 'Manager') as ManagerCount
from ...
I think you can use a simple WHERE clause to select only the count some record.