Counting from 2 columns in SQL server - sql

In essence I have one table with two columns
One Two
-----------
A B
B C
C D
and I want to count the number of A's through D.
Resulting
Letter Count
---------------
A 1
B 2
C 2
D 1
My code now is
Select one, count("") from table
group by one
union
Select two, count("*") from table
group by two
Right now I am getting
Letter Count
---------------
A 1
B 1
B 1
C 1
C 1
D 1
How do I fix it?

Try this
SELECT Count(a),
a
FROM (SELECT cola a
FROM table
UNION ALL
SELECT colb a
FROM table) c
GROUP BY a

select letter, sum(total) from
(
Select one as letter, count(1) as total from tablename
group by one
union all
Select two as letter, count(1) as total from tablename
group by two) as t1
group by t1.letter
order by t1.letter asc

there is no reason to group twice.
select letter, count(*) as total_cnt
from
(
Select one as letter from table
union all
Select two as letter from table
)
group by letter;

You can do this
SELECT LETTER,
count(*) AS _count
FROM (
SELECT One AS Letter
FROM Test
UNION ALL
SELECT Two AS Letter
FROM Test
) T1
GROUP BY LETTER

Related

Sql in oracle to find out missing records from its distinct values

I am sorry , this one is not working... May be I should have clarified this earlier. The values A,B,C,D etc... Are the Distinct values for CODE in the Table. There are several hundreds of IDs in the table and each ID can have one to many Code values. In the above example assume that there are 5 distinct values of Code from table A. There are 3 IDs and each ID is associated in Table A as follows
ID Code
1 A
1 B
1 C
2 D
2 A
3 B
3 C
4 A
4 B
4 C
4 D
4 E
As you see above there are several IDs associated with different Code values. I need the result as follows
ID CODE
1 D
1 E
2 B
2 C
2 E
3 A
3 D
3 E
ID 4 should not return anything because it contain all possible Codes (in this case A,B,C,D,E)
First you should take distinct values for both column in different sub-query, second cross join them - that will give you all possible combination,
finally exclude combination which are already presnet
select *
from
(select distinct ID
from your_table) ytI, /* this sub-query will return all possible ID */
(select distinct code
from your_table) ytc /* this sub-query will return all possible code */
where (ytI.ID,ytc.Code) /* there will be cross-join as there are no join condition between first two tables*/
not in /* exclude those records which are already present */
(select id,code
from your_table yt_i)
try this
select T2.ID, T1.missing_value
from
(
select 'A' missing_value from dual UNION
select 'B' from dual UNION
select 'C' from dual UNION
select 'D' from dual UNION
select 'E' from dual
) T1,
(
select distinct id from MYTABLE
) T2
WHERE NOT EXISTS
(
SELECT * FROM MYTABLE M WHERE M.CODE = T1.missing_value and M.ID = T2.ID
)
ORDER BY T2.ID, T1.missing_value

How to exclude some (not all) record that has same values

After query table A using first query, I have these records:
pID cID code
1 1 A
1 1 B
1 1 B
1 1 B
After query table B using second query, I have one record:
pID cID code
1 1 B
1 1 B
I want table A exclude the records of table B. The result is:
pID cID code
1 1 A
1 1 A
How can I do that? Hope u could help me. thanks.
Updating...
Sorry for the example to make you confuse
If I got these record from second table:
pID cID code
1 1 B
Then the result I want is (exclude one record):
pID cID code
1 1 A
1 1 B
1 1 B
you try GROUP BY function in your Query
example :
select pID,cID,code from table group by code
using EXCEPT and row_number() to generate a unique no
;with cte1 as
(
select *, rn = row_number() over (partition by pID, cID, code order by pID, cID, code)
from query1
),
cte2 as
(
select *, rn = row_number() over (partition by pID, cID, code order by pID, cID, code)
from query2
)
select *
from cte1
except
select *
from cte2
Based on your question, which I think you want to delete the records from B which occur more than once in A:
first select all records from A which are not there in B and then union them 1 distinct records which are there in both A and B:
select * from A
except
select * from B
union all
select distinct *
from
(select a.pid, a.cid, a.code
from
A
inner join
B
on a.pid=b.pid and a.cid=b.cid and a.code=b.code)
Just use EXCEPT. How ever your desired output is wrong as 1 1 B also the same record from TableB
SELECT * FROM TABLE_A
EXCEPT
SELECT * FROM TABLE_B
Refer this Link
If your case NOt all But some then.
Simply you can use DISTINCT
As per the UPdate in Question (From what I understood)
SELECT DISTINCT * FROM TABLE_A
UNION ALL
SELECT * FROM TABLE_B

GROUP BY one column to find MAX, but keep value from another column - SQL

A | B | num
----------------------
123 1 2
123 10 5
Result:
A | B | max_num
-------------------------
123 10 5
Let's say the table name is tab, currently I have
SELECT T.A, MAX(T.num) AS max_num
FROM tab T
GROUP BY T.A
However, the result will not contain the column B.
SELECT T.A, T.B... GROUP BY T.A, T.B
Will also not give the desired result, since max is found based on the A,B pair.
How can I choose the max of num grouped by only A, but then keep the value of B for the max row that is chosen?
1.Select Max num from table
2.Just filter of IN Clause
select * from Mytable where
num in(
select TOP 1 MAX(num)
from mytab
group by colA)
or
For SQL SERVER
You can Use Window function for single Max using ROW_NUMBER ()
select * from (
select ROW_NUMBER () OVER (ORDER BY num desc) rn,*
from tab
)d where d.rn=1
This should do the job:
Select t1.A, T1.B,T1.num from tab t1 where (T1.A,T1.num) in (
SELECT T.A, MAX(T.num) AS max_num
FROM tab T
GROUP BY T.A)
Selection the Record where num equals the max(num)
See the SQLFIDDLE
Do you mean you want the whole rows where c = the max(c) value for each a? This one will give both rows if it's a tie:
select a, b, c
from t as t1
where c = (select max(c) from t t2
where t1.a = t2.a)

sql query to count two columns with same values

I've got a table with 2 columns with keywords, and I need to count the occurrence of them.
I can do that separately, one column at the time, and add the totals later, with a regular count,
select count (id), kw1 from mytable group by kw1
and the same for kw2, but I need to get the info straight from the db.
So the table is something like:
id kw1 kw2
1 a b
2 c d
3 b
4 e a
so the idea is to get how many times has been used each keyword, so the result should be something like:
'a' 2
'b' 2
'c' 1
'd' 1
'e' 1
Thanks in advance
PS: Sorry, I forgot, but just in case, I'm working on Oracle 10g
Try this:
SELECT kw, COUNT(kw)
FROM
(
SELECT "kw1" AS kw FROM table1
UNION ALL
SELECT "kw2" FROM table1
) t
WHERE kw IS NOT NULL
GROUP BY kw
ORDER BY KW;
SQL Fiddle Demo
This will give you:
KW COUNT(KW)
a 2
b 2
c 1
d 1
e 1
It shoud looks something like this.
SELECT kw,SUM(kw)
FROM(
(SELECT kw1 AS kw, COUNT(kw1)
FROM table
WHERE kw1 IS NOT NULL GROUP BY kw1) skw1
UNION ALL
(SELECT kw2, COUNT(kw2)
FROM table
WHERE kw2 IS NOT NULL GROUP BY kw2) skw2
)
GROUP BY kw
ORDER BY kw
Previous answers don't perform a SUM operation after performing the UNION.
use union All to combine two column data into one column & then count occurence
SELECT cnt, COUNT(cnt)
FROM
(
SELECT kw1 AS cnt FROM table
UNION ALL
SELECT kw2 FROM table
) t
WHERE cnt IS NOT NULL
GROUP BY cnt
ORDER BY cnt;

get subset of a table in SQL

I want to get a subset of a table, here's the example:
1 A
2 A
3 B
4 B
5 C
6 D
7 D
8 D
I want to get the unique record, but with the smallest id:
1 A
3 B
5 C
6 D
How can I write the SQL in SQL Server? Thanks!
Use a common-table expression like this:
;WITH DataCTE AS
(
SELECT ID, OtherCol,
ROW_NUM() OVER(PARTITION BY OtherCol ORDER BY ID) 'RowNum'
FROM dbo.YourTable
)
SELECT *
FROM DataCTE
WHERE RowNum = 1
This "partitions" your data by the second column you have (A, B, C) and orders by the ID (1, 2, 3) - smallest ID first.
Therefore, for each "partition" (i.e. each value of your second column), the entry with RowNum = 1 is the one with the smallest ID for each value of the second column.
select min(id), othercol
from thetable
group by othercol
and maybe with
order by othercol
... at the end if thats important
Try this:
SELECT MIN(Id) AS Id, Name
FROM MyTable
GROUP BY Name
select min(id), column2
from table
group by column2
It helps if you provide the table information in the question - I've just guessed at the column names...