How to get distinct count over multiple columns in SQL? - sql

I have a table that looks like this. And I want to get the distinct count across the three columns.
ID
Column1
Column 2
Column 3
1
A
B
C
2
A
A
B
3
A
A
The desired output I'm looking for is:
ID
Column1
Column 2
Column 3
unique_count
1
A
B
C
3
2
A
A
B
2
3
A
A
1

You want to use cross apply for this one.
select *
from t cross apply
(select count(distinct cnt) as unique_count
from (values(Column1),(Column2),(Column3)) t(cnt)) t2
ID
Column1
Column2
Column3
unique_count
1
A
B
C
3
2
A
A
B
2
3
A
A
1
Fiddle

In standard SQL, you have to UNPIVOT first, do the count(distinct) group by on the PIVOTed result and then PIVOT again.
In recent ORACLE version, you could write your own Polymorphic Table Function to do it, passing the table and the list of columns to count for DISTINCT values.

try if this works
SELECT Count(*)
FROM (SELECT DISTINCT Column1 FROM TABLENAME);

Related

Shows rows with different values for single ID

I have a (part of a) table that looks like this:
Some_ID Some_Value
1 A
2 B
3 C
3 C
3 D
4 E
4 E
4 E
I want to find all rows that has different values per ID, so for this example my output should be:
Some_ID Some_Value
3 C
3 C
3 D
It doesn't even have to look like this, it would also be enough to just get the IDs without the values.
Any ideas?
You could use this:
SELECT some_id
FROM table_name
GROUP BY some_id
HAVING COUNT(DISTINCT some_value) > 1
ORDER BY some_id;
Have a sub-query that returns Some_ID's having more than 1 different Some_Value. JOIN with that result:
select t1.Some_ID, t1.Some_Value
from tablename t1
join (select Some_ID
from tablename
group by Some_ID
having count(distinct Some_Value) > 1) t2
on t1.Some_ID = t2.Some_ID

Which kind of join do I need to use here?

For every row in table Y, I need a copy of the current row in Table X, taking field 1 from Table Y.
Table X
Field 1 Field 2
null A
null B
null C
Table Y
Field 1
1
2
3
Desired output
Field 1 Field 2
1 A
1 B
1 C
2 A
2 B
2 C
3 A
3 B
3 C
Looks like a cross join:
select y.field1, x.field2
from x cross join
y;
Looks like an unconditional select of both tables without matching ids
Something like
select tableY.column1, tableX.column2
from tableY, tableX
order by tableY.column1 asc, tableX.column2 asc
should do it.
BTW. Was this a school question, because then I should not have answered this.
Try this query:
SELECT #Tabley.Field1 , #TableX.Field2
FROM #TableX ,#Tabley

Merge data into one column - sql server 2012

How can I merge data into one column for different account numbers. Currently, it looks like this.
TableA.Order TableA.Question TableB.Response
1 a Null
1 b James
1 c Null
2 d Zebra
2 T Null
However, I want it to merge like below:
TableA.Order NewColumn
1 a
1 b
1 c
1 James
2 d
2 T
2 Zebra
Base from my understanding of your question. I devised a solution which answers to it. See my query below:
SELECT * FROM TableA
UNION ALL
SELECT B.Order1,A.Response From
(
(SELECT ROW_NUMBER()OVER(ORDER BY Response)PK,* FROM TableB) A Left Join
(SELECT ROW_NUMBER()OVER(ORDER BY Order1)PK,* FROM TableA) B On A.PK=B.PK
)
Where Response IS NOT NULL

How SQL join work?

i am using MYSQL..
I have two tables:
TABLE 1 (TABLE NAME T1)
SL NAME
1 a
2 b
3 c
4 c
table 2 (table name T2)
SL NAME
1 a
2 c
3 c
4 c
Q1: how i count the total number of 'c' in both table?
Q2: which name is max occurrences in both table?
sl is primary key...
my query is:>
select count(*) from t1,t2
where t1.name=t2.name where t1.name='c';
but it showing 6
To count c in both tables you should use UNION, not JOIN.
Syntax:
SELECT ...
UNION [ALL | DISTINCT] SELECT ...
[UNION [ALL | DISTINCT] SELECT ...]
Doc:
http://dev.mysql.com/doc/refman/5.0/en/union.html
Edit:
I'll explain the query that you provided.
select count(*) from t1,t2 where t1.name=t2.name where t1.name='c';
First of all, you use WHERE clause twice which is a syntax error. Should be:
select count(*) from t1,t2 where t1.name=t2.name AND t1.name='c';
And this is the same that:
SELECT count(*) from t1
JOIN t2 ON t1.name=t2.name
WHERE t1.name='c';
You choose only rows with c value so these are the rows, that we will take under consideration:
TABLE 1 (TABLE NAME T1)
SL NAME
3 c
4 c
table 2 (table name T2)
SL NAME
2 c
3 c
4 c
Now, simple JOIN joins every row from table 1 to every row from table 2 (where condition is true of course)
So the result before counting is:
t1.SL t1.NAME t2.SL t2.NAME
3 c 2 c
4 c 3 c
3 c 4 c
4 c 2 c
3 c 3 c
4 c 4 c
This is 6 rows.
Answers for both of your questions.
SELECT name, count(*) as cnt
FROM(select t1.name from t1
union all
select name from t2) as tem
group by name
order by cnt DESC
This query will give you ranking of names ordered by occurrences.
To retrieve only c count, just add WHERE clause. To retrieve only the most occurring name set LIMIT clause to 1.
INSERT INTO #test
SELECT NAME FROM m_t1 WHERE NAME ='c'
UNION all
SELECT NAME FROM m_t2 WHERE NAME ='c'
SELECT count(*) FROM #test

SELECT only records which must fill two conditions

I have this table:
id type otherid
1 4 1234
2 5 1234
3 4 4321
As you can see there are 3 records, 2 of them belongs to otherid "1234" and got type of 4 and 5.
Last record belongs to otherid of "4321" and has only a type of 4.
I need to select all otherid that got only the type 4 and not the type5.
Example: after this select on that table the query shuould return only the record 3
Thanks
add1:
Please consider the TYPE can be any number from 1 up to 20.
I only need otherid that got type 4 but not type 5 ( except than that they can have any other type )
add2:
using mysql 5.1
This is kind of a workaround
SELECT * FROM (
SELECT GROUP_CONCAT('|',type,'|') type,other_id FROM table GROUP BY otherid
) t WHERE type LIKE '%|4|%' AND type NOT LIKE '%|5|%'
You could use a not exists subquery:
select distinct otherid
from YourTable as yt1
where yt1.type = 4
and not exists
(
select *
from YourTable as yt2
where yt1.otherid = yt2.otherid
and yt1.type <> yt2.type -- use this line for any difference
and yt2.type = 5 -- or this line to just exclude 5
)
Another way is by using a left join from where you exclude rows that have both type 4 and 5:
select a.*
from table1 a
left join table1 b on b.otherid = a.otherid and b.type = 5
where a.type = 4 and b.id is null