Challenge with Not Equal to operator - sql

I have a problem to solve. I would like to get the countries where the gender not equal to Female from the following table using only the where clause. I don't want to use the sub query like: select country from table where country not in (select country from table where gender='Female')
Any ideas ?
ID Name Gender Country
1 Jhon Male USA
2 Katie Female USA
3 Steave Male UK
4 Gerry Female UK
5 Brad Male AUS
Regards,
Chandra.

Use not exists
select t.*
from table t
where not exists (select 1
from table
where Country = t.Country and
Gender = 'Female'
);
You can also use group by like that :
select Country
from table t
group by Country
having sum(case when Gender = 'Female' then 1 else 0 end) = 0;

You could avoid subquery and get full rows by using:
SELECT TOP 1 WITH TIES *
FROM tab
ORDER BY SUM(CASE WHEN Gender='Female' THEN 1 ELSE 0 END)
OVER(PARTITION BY Country);
DBFiddle Demo - SQL Server

You can do:
select country
from t
except
select country
from t
where gender = 'Female';
As a set operator, except removes duplicates.

Maybe I got your question wrong but why you don't use:
SELECT country FROM table WHERE gender NOT IN('Female')
Or is it a sub query?

Related

Count results that have different column value related to same ID

I'm new to SQL and looking for help on how to best do this.
I have 2 tables with the following columns:
Investors: Round ID, Investor Name, Investor City, Investor Country
Rounds: Round ID, Company Name, Company City, Company Country
I joined them to get this result
Round ID
Investor Country
Company Country
1
US
Spain
1
UK
Spain
1
Spain
Spain
2
France
Germany
2
UK
Germany
3
UK
Italy
3
Italy
Italy
I will need to get the number of investors (per round ID) which have their country different from the Company Country, So like for Round 1 I will have 2, for Round 2 it's 0 and for round 3 it's 1.
How could I do this?
Thank you for your help!
Just use conditional aggregation:
select round,
sum(case when investor_country <> company_company then 1 else 0 end) as cnt
from t
group by round;
Looking at your expected output, I think you need the count = 0 in case there do not exists a single record for investor country = company country and if there is, then you need all other record count.
You can use conditions as follows:
select round_id,
case when count(case when investor_country = company_company then 1 end) = 0
then 0
else count(case when investor_country <> company_company then 1 end)
end as cnt
from your_table t
group by round_id;
If you need diffrent counts:
SELECT
RoundId,
SUM(IIF(InvestorCountry != CompanyCountry,1,0)) AS Count
FROM
YOUR_TABLE_OR_VIEW
GROUP BY
RoundId
If you need difrent count and when all result of a same Round are difrent you want zero:
SELECT
t.RoundId,
IIF(t.Count = t.DiffrentCount,0,t.DiffrentCount) 'Count'
FROM
(
SELECT
RoundId,
SUM(1) AS 'Count',
SUM(IIF(InvestorCountry != CompanyCountry,1,0)) AS 'DiffrentCount',
FROM
YOUR_TABLE_OR_VIEW
GROUP BY
RoundId
)t

PostgreSQL - How to extract multiple data from a column in postgresql

I have a table in postgres:
Description
Value
Name
Jane
Last name
Doe
Age
23
Country
USA
And I want it like this:
Name
Last_name
Age
Country
Jane
Doe
23
USA
Please help :)
You can use conditional aggregation. In normal situation, your table has more than 3 rows, and there is another column that identifies which rows belong to the same person - say person_id:
select person_id,
max(case when description = 'Name' then value end) as name,
max(case when description = 'Last name' then value end) as last_name,
max(case when description = 'Age' then value end) as age,
max(case when description = 'Country' then value end) as country
from mytable
group by person_id

Substraction by the column just created in bigquery

My query is supposedly create new column based on the keyword in data using bigquery. For example if in data consists 'Mike' it will create Mike column, 'John' will create John column and the list goes on..
However, I want to create a 'other' column that is the substraction of overall name with the column I just created.
My code example (wrong at SUBSTRACT function):
SELECT
COUNT(Name) as n_name,
SUM(CASE WHEN Name LIKE '%MIKE%' THEN 1 ELSE 0 END) AS Mike,
SUM(CASE WHEN Name LIKE '%JOHN%' THEN 1 ELSE 0 END) AS John,
SUM(CASE WHEN Name LIKE '%MICHAEL%' THEN 1 ELSE 0 END) AS Michael,
.....
SUBSTRACT (n_name ,Mike and John) AS Others
FROM t
Is there any way to do some substraction by the column I just created ?
you can use below approach (BigQuery Standard SQL)
SELECT *,
n_name - Mike - John - Michael AS Other
FROM (
SELECT
COUNT(Name) AS n_name,
COUNTIF(Name LIKE '%MIKE%') AS Mike,
COUNTIF(Name LIKE '%JOHN%') AS John,
COUNTIF(Name LIKE '%MICHAEL%') AS Michael,
FROM t
)
SELECT
*
,n_name - Mike - John - Michael AS Other
FROM
(
SELECT
COUNT(Name) AS n_name
,COUNT(CASE WHEN Name like '%MIKE%' THEN 1 END) AS Mike
,COUNT(CASE WHEN Name LIKE '%JOHN%' THEN 1 END) AS John
,COUNT(CASE WHEN Name LIKE '%MICHAEL%' THEN 1 END) AS Michael
FROM
t
) aa

How to count the number of times a specific text string appears and group it by other columns

I have a table population_table that contains columns with a user_id, provider_name, and city. I want to count the number of times a user appears in each city, per provider. So for instance, I would want the output to look something like this:
provider_name | Users | Atlanta | Chicago | New York
______________________________________________________
Alpha 100 50 25 25
Beta 200 100 75 25
Kappa 500 300 100 100
I tried using:
select provider_name, count (distinct user_id) AS Users, count(city) AS City
from population_table
group by provider_name
How can I write this query to get the breakdown of the users per provider per city?
I think you want conditional aggregation. It is not clear from your description that count(distinct) is necessary. So I would try this first:
select provider_name, count(*) AS Users,
sum(case when city = 'Atlanta' then 1 else 0 end) as Atlanta,
sum(case when city = 'Chicago' then 1 else 0 end) as Chicago,
sum(case when city = 'New York' then 1 else 0 end) as New_York
from population_table
group by provider_name;
If count(distinct) is necessary:
select provider_name, count(distinct user_id) AS Users,
count(distinct case when city = 'Atlanta' then user_id end) as Atlanta,
count(distinct case when city = 'Chicago' then user_id end) as Chicago,
count(distinct case when city = 'New York' then user_id end) as New_York
from population_table
group by provider_name
If you have a variable number of cities, I do not know how to supply the list in SparkSQL. But using pyspark, you could create output table from input like this:
counts = input.groupBy('provider_name', 'city').count().cache()
countsPerProvider = counts.groupBy('provider_name').count().withColumnRenamed("count", "users")
pivoted = counts.groupBy("provider_name").pivot("city").sum('count')
table = pivoted.join(countsPerProvider, pivoted["provider_name"] == countsPerProvider["provider_name"]).select(pivoted["*"], countsPerProvider["users"])

How to find rows where the same column has only the same another column

Suppose following table:
Name Age Occupation
Alex 20 Student
Alex 20 Seller
Alex 20 Minister
Liza 19 Student
Liza 20 Volunteer
Liza 21 HR partner
I want to find names which have only (and only) 20 in age column. So from this table I want to get all "Alex" rows and no "Liza" rows at all.
Thanks!
You need to use Group By and Having clause. Try this way
select Name
from table
group by Name
having count(case when Age = 20 then 1 end) = count(*)
count(case when Age = 20 then 1 end) counts only when age = 20 if it is equal to total count then the name has only 20 as age.
Just one another way:
select Name
from table
group by Name
having min(Age) = 20 and max(Age) = 20
One way is using NOT IN():
SELECT Name, Age, Occupation
FROM YourTable
WHERE Age = 20
AND Name NOT IN (SELECT Name FROM YourTable WHERE Age <> 20)