Let's say I have a table called "matches" where I save 2 teams from a soccer match.
-------------------------
| home_club | away_club |
-------------------------
| | |
-------------------------
And I have a query that returns all the clubs from that table, both the home and away clubs through UNION:
SELECT home_club AS clubs FROM matches UNION SELECT away_club FROM matches
Now I have a results set called "clubs" and I wish to count how many times each has appeared in the "matches" table. How do I go about doing this?
If you want to know how many times each has appeared in the matches table, then you need to get rid of the union in the subquery. The union is going to remove duplicates.
Here is how you would get a count:
select club, count(*) as NumAppears
from (SELECT home_club AS club FROM matches
UNION ALL
SELECT away_club FROM matches
) m
group by club;
Note the UNION is replaced with UNION ALL.
Try following
select sum(count) as Matches, Club from
(select count(*) as count, home_club as Club from matches group by home_club
union all
select count(*) as count, away_club as Club from matches group by away_club ) a
group by a.clubs
SELECT
M.clubs,
COUNT(M.clubs) [count]
FROM
(
SELECT
home_club AS clubs
FROM
matches
UNION ALL
SELECT
away_club
FROM
matches
) M
GROUP BY
M.clubs
Related
Given this data
id Name group
1 Jhon 001
2 Paul 002
3 Mary 001
How can I get the duplicates values showing all the fields? The duplicate is only on group, id and name won't be duplicates.
Should end up looking like one of those (any would be valid):
:::::::::::::::::::::::::::::::::::::::::::::::
group count values
001 2 1,3
:::::::::::::::::::::::::::::::::::::::::::::::
id name group
1 Jhon 001
3 Mary 001
I tried with
SELECT
group, COUNT(*)
FROM
people
GROUP BY
group
HAVING
COUNT(*) > 1
But if I try to add id and name to the group by, it won´t find any duplicate.
Thanks in advance.
Try this.
SELECT Id, Name, [Group]
FROM people
WHERE [Group] IN(
SELECT [Group]
FROM people
GROUP BY [Group]
HAVING COUNT(*) > 1)
I would do an inner query to find the groups with more than one member, and then use that inner query to bring back a list of the names.
For example:
SELECT Id, Name, group
FROM people
WHERE group in
(SELECT group
FROM people
GROUP BY group
HAVING count(*) > 1);
Avoid using Group because it is a reserved keyword in SQL :
SELECT *
FROM MyTable
WHERE groups IN(
SELECT groups
FROM MyTable
GROUP BY groups
HAVING COUNT(*) > 1)
Check Execution here
Just use exists:
select p.*
from people p
where exists (select 1
from people p2
where p2.group = p.group and
p2.id <> p.id
);
This should be the most performant solution. With an index on people(group, id), it should have very good performance.
Note: All the advice to avoid using group as a column name is good advice. You should change the name.
Is there any difference between COUNT(*) and COUNT(attribute_name)?
I used count(attribute_name) as I thought that it would be specific hence the searching process would be easier. Is that true?
It would be great to see any example with sql code with my issue to help me understand better
Imagine this table:
select Count(TelephoneNumber) from Calls -- returns 3
select Count(*) from Calls -- returns 4
count(column_name) also counts duplicate values. Consider:
select Count(TelephoneNumber) from Calls -- returns 4
COUNT(*) counts all the records in the group.
COUNT(column_name) only counts non-null values.
There is also another typical expression, COUNT(DISTINCT column_name), that counts non-null distinct values.
Since you asked for it, here is a demo on DB Fiddlde:
with t as (
select 1 x from dual
union all select 1 from dual
union all select null from dual
)
select count(*), count(x), count(distinct x) from t
COUNT(*) | COUNT(X) | COUNT(DISTINCTX)
-------: | -------: | ---------------:
3 | 2 | 1
COUNT(*) will count all the rows.
COUNT(column) will count non-NULLs only.
Your can use of COUNT(*) or COUNT(column) which should be based on the desired output only.
Consider below Example of employee table
ID Name Description
1 Raji Smart
2 Rahi Positive
3
4 Falle Smart
select count(*) from employee;
Count(*)
4
select count(name) from employee;
Count(Name)
3
count() only counts non-null values. * references the complete row and as such never excludes any rows. count(attribute_name) only counts rows where that column is no null.
So this:
select count(attribute_name)
from the_table
is equivalent to:
select count(*)
from the_table
where attribute_name is not null
The difference is simple: COUNT(*) counts the number of rows produced by the query, whereas COUNT(1) counts the number of 1 values. Note that when you include a literal such as a number or a string in a query, this literal is "appended" or attached to every row that is produced by the FROM clause.
For more detail this link would help you understand.
I currently want to do some sort of conditional union. Given the following example:
SELECT age, name
FROM users
UNION
SELECT 25 AS age, 'Betty' AS name
Say I wanted to only union the second statement if the count of 'users' was >=2 , otherwise do not union the two.
In summary I want to append a table with a row if the table only has 2 or more values.
You could use an ugly hack something like this, but I think Tim's answer is better:
SELECT age, name
FROM users
UNION ALL
SELECT 25, 'Betty'
WHERE (SELECT COUNT(*) FROM users) > 1;
If it's in a stored-procedure you could use If...Else:
IF (SELECT COUNT(*) FROM users) < 2
BEGIN
SELECT age, name
FROM users
END
ELSE
SELECT age, name
FROM users
UNION ALL
SELECT 25 AS age, 'Betty' AS name
Otherwise you could try something like this:
SELECT age, name
FROM users
UNION ALL
SELECT TOP 1 25 AS age, 'Betty' AS name
FROM users
WHERE (SELECT COUNT(*) FROM users) >= 2
Note that i've used UNION ALL since it doesn't seem that you want to eliminate duplicates.
Played around here: http://sqlfiddle.com/#!6/a7540/2323/0
Edit: Instead of my second approach i prefer Zohar's. So if you can use If....Else prefer that otherwise WHERE (SELECT COUNT(*) FROM users) > 1 without a table.
Something like the following should work:
SELECT age, name
FROM users
UNION ALL
SELECT age, name
FROM (SELECT 25 AS age, 'Betty' AS name) x
CROSS APPLY (SELECT COUNT(*) FROM users) y(cnt)
WHERE y.cnt >= 2
Second part of UNION ALL will be NULL in case users table has less than 2 records.
SELECT age
, name
FROM users
UNION
SELECT 25 As age
, 'Betty' As name
WHERE EXISTS (
SELECT Count(*)
FROM users
HAVING Count(*) >= 2
)
;
I used the following query and it returned what I wanted it to return, but I'm having a tough time wrapping my head around what the query is doing.
Query is nothing fancier than what's in the title: select distinct(count(*)) from table1
Distinct is not required in your SQL ,as you are going to get only result, count(*) without group by clause returns, count of all rows within that table.
Hence try this :
select count(*) from table1
Distinct is used for finding distinct values from a group of values:
say you have table1 , with column1 as :
Column1
----------
a
a
b
b
a
c
following sqls are run you will get output as :
1) select count(*) from table1
output :6
2) select distinct(count(*)) from table1
output :6
3) select count( distinct column1) from table1
output :3
Usually distinct is used inside count preferably with a particular column .
select count( distinct column_name_n ) from table1
The distinct is redundant... Select Count(*) with only one table can only generate one value, so distinct (which would eliminate duplicates) is irelelvant.
If you had multiple outputs, (if for example you were grouping on something) then it would cause the query to only display one output row for every distinct value of count(*) that would other wise be generated...
if, for example, you had
name
Bob
Bob
Bob
Bob
Mary
Mary
Mary
Mary
Dave
Dave
Al
George
then
select count(*)
From table
group By name
would result in
4
4
2
1
1
but
select distinct count(*)
From table
group By name
would result in
4
2
1
Does anyone happen to know a way of basically taking the 'Distinct' command but only using it on a single column. For lack of example, something similar to this:
Select (Distinct ID), Name, Term from Table
So it would get rid of row with duplicate ID's but still use the other column information. I would use distinct on the full query but the rows are all different due to certain columns data set. And I would need to output only the top most term between the two duplicates:
ID Name Term
1 Suzy A
1 Suzy B
2 John A
2 John B
3 Pete A
4 Carl A
5 Sally B
Any suggestions would be helpful.
select t.Id, t.Name, t.Term
from (select distinct ID from Table order by id, term) t
You can use row number for this
Select ID, Name, Term from(
Select ID, Name, Term, ROW_NUMBER ( )
OVER ( PARTITION BY ID order by Name) as rn from Table
Where rn = 1)
as tbl
Order by determines the order from which the first row will be picked.