Count two columns in one - sql

I have two columns (user_from and user_to) and I need to know how many different users appears in my database. What is a good and fast way to do that?
I'm using PostgreSQL, btw.

select distinct tmp.UserName from
(
select distinct user_from as UserName from YourTable
union
select distinct user_To as UserName from YourTable
) as tmp;

This query is quite sufficient to get the list of users:
select user_from as UserName
from t
union -- intentional to remove duplicates
select user_To as UserName
from t;
If you want the count, then:
select count(*)
from (select user_from as UserName
from t
union
select user_To as UserName
from t
) t;

Related

Is it possible to UNION distinct rows but disregard one column to determine uniqueness?

select d.id, d.registration_number
from DOCUMENTS d
union
select dd.id, dd.registration_number
from DIFFERENT_DOCUMENTS dd
Would it be possible to union those results based solely on the uniqueness of the registration_number, disregarding the id of the documents?
Or, is it possible to achieve the same result in a different way?
Just to add: actually I'm unioning 5 queries, each ~20 lines long, with 4 columns that should be disregarded in determining uniqueness.
you basically need to wrap the unioned data with something else to get only the ones you want.
SELECT min(id), registration_number
FROM (SELECT id, registration_number
FROM documents
UNION ALL
SELECT id, registration_number
FROM different_documents)
GROUP BY registration_number
Union will check the combination of all the columns for uniqueness. You could, however, use union all (that does not remove duplicates) and then apply the logic yourself using the row_number window function:
SELECT id, registration_number
FROM (SELECT id, registration_number,
ROW_NUMBER() OVER (PARTITION BY registration_number ORDER BY id) AS rn
FROM (SELECT id, registration_number
FROM documents
UNION ALL
SELECT id, registration_number
FROM different_documents) u
) r
WHERE rn = 1
Since the other answers are already correct, may I ask why do you need to retrieve other columns in that query since the primary purpose appear to gather unique registration numbers?
Wouldn't it be simpler to first gather unique registration number and then retrieve the other info?
Or in your actual query, first gather the info without the columns that should be disregarded and then gather the info in these column if need be?
Like,for example, making a view with
SELECT d.registration_number
FROM DOCUMENT d
UNION
SELECT dd.registration_number
FROM DIFFERENT_DOCUMENT dd
and then gather information using that view and JOINS?
Assuming registration_number is unique in each table, you can use not exists:
select d.id, d.registration_number
from DOCUMENTS d
union all
select dd.id, dd.registration_number
from DIFFERENT_DOCUMENTS dd
where not exists (select 1
from DOCUMENTS d
where dd.registration_number = d.registration_number
);

count all the distinct records in a table

I need to count all the distinct records in a table name with a single query and also without using any sub-query.
My code is
select count ( distinct *) from table_name
It gives an error:
Incorrect syntax near '*'.
I am using Microsoft SQL Server
Try this -
SELECT COUNT(*)
FROM
(SELECT DISTINCT * FROM [table_name]) A
I'm afraid that if you don't want to use a subquery, the only way to achieve that is replacing * with a concatenation of the columns in your table
select count(distinct concat(column1, column2, ..., columnN))
from table_name
To avoid undesired behaviours (like the concatenation of 1 and 31 becoming equal to the concatenation of 13 and 1) you could add a reasonable separator
select count(distinct concat(column1, '$%&£', column2, '$%&£', ..., '$%&£', columnN)
from table_name
You can use CTE.
;WITH CTE AS
(
SELECT DISTINCT * FROM TableName
)
SELECT COUNT(*)
FROM CTE
Hope this query gives you what you required.
As others mentioned, you cannot use DISTINCT with *. Also it is good practice to use a column name instead of the *, like a unique key / primary key of the table.
SELECT COUNT( DISTINCT id )
FROM table
select distinct Name , count(Name) from TableName
group by Name
having count(Name)=1
select ##rowcount
I had the same issue involving a query that had multiple joins to tables and I could not simply do count(distinct ) or count(distinct alias.).
My solution was to create a string made up of the key columns I cared about and count them.
SELECT Count(DISTINCT person.first || '~' || person.last)
from person;
If you want to use DISTINCT keyword, you need to specify column name on which bases you want to get distinct records.
Example:
SELECT count(DISTINCT Column-Name) FROM table_name

nested select in sql server 2008

I save user logins in a table that named loginstats, I want to retrieve last login of every users, I use these code but I meet some error, What is my mistake?
select *
from loginStats
where id in (
select distinct username, MAX(id) as id
from loginStats
group by username)
You are doing id IN, but are trying to compare it to multiple columns. Try this instead:
SELECT A.*
FROM LoginStats A
INNER JOIN (SELECT DISTINCT username, MAX(id) as id
FROM loginStats
GROUP BY username) B
ON A.username = B.username AND A.id = B.id
select *
from loginStats
where id in (
select distinct MAX(id) as id
from loginStats
group by username)
You can't have multiple field outputs in your IN subquery.
Or you could also do this like this:
;WITH CTE
AS
(
SELECT
RANK() OVER(
PARTITION BY loginStats.username
ORDER BY loginStats.id DESC
) AS iRank,
loginStats.*
FROM
loginStats
)
SELECT
*
FROM
CTE
WHERE
CTE.iRank=1
Here is some information how to use the rank function and how it is applied.
Here is some information on msdn about the rank function.
Here is some information about cte function and usage
Here is some information about With clause and how it is used
Hope it helps you understand
The mistake is that in the IN clause only one column can be specified and you are specifying two: username and id.
You're selecting two fields, where you should only return one. This correlated subquery should work for you:
select *
from loginStats AS a
where id = (
select MAX(id) as id
from loginStats AS b
where b.username = a.username)

Select everything, based on distinct USER ID in Oracle

I am trying to select * from an oracle table, but only where user_id are unique.
i tried this:
select distinct user_id from users; -- which worked
i want to display EVERYTHING, so when i put:
select distinct user_id, * from users; -- i get a syntax error
how can i accomplish his?
select distinct user_id, users.* from users;
select * from users where users.primary_key IN
(select primary_key FROM users GROUP BY user_id HAVING count(*) = 1)
This will only select records that do not share user_ids with other rows.

How to count distinct values in SQL union?

I can select distinct values from two different columns, but do not know how to count them.
My guess is that i should use alias but cant figure out how to write statement correctly.
$sql = "SELECT DISTINCT author FROM comics WHERE author NOT IN
( SELECT email FROM bans ) UNION
SELECT DISTINCT email FROM users WHERE email NOT IN
( SELECT email FROM bans ) ";
Edit1: i know that i can use mysql_num_rows() in php, but i think that takes too much processing.
You could wrap the query in a subquery:
select count(distinct author)
from (
SELECT author
FROM comics
WHERE author NOT IN ( SELECT email FROM bans )
UNION ALL
SELECT email
FROM users
WHERE email NOT IN ( SELECT email FROM bans )
) as SubQueryAlias
There were two distincts in your query, and union filters out duplicates. I removed all three (the non-distinct union is union all) and moved the distinctness to the outer query with count(distinct author).
You can always do SELECT COUNT(*) FROM (SELECT DISTINCT...) x and just copy that UNION into the second SELECT (more precisely, it's called an anonymous view).