My table looks like:
id A B
1 1 3
2 2 3
3 3 1
I want SELECT only unique AB pairs
13 is unique
23 is unique
31 not unique because pair 13 exists
Trying with SELECT a, b FROM test GROUP BY a, b but query return 3 pairs
You can use least() and greatest() functions both in SELECT-list and GROUP BY expression :
SELECT least(a, b) , greatest (a,b)
FROM test
GROUP BY least(a, b) , greatest (a,b)
Demo
Or just use DISTINCT within the SELECT-list :
SELECT DISTINCT least(a, b) , greatest (a,b)
FROM test
Below query may use indices.
SELECT DISTINCT a, b
FROM test
WHERE a >= b
UNION ALL
SELECT DISTINCT a, b
FROM test t1
WHERE a < b
AND NOT EXISTS ( SELECT NULL
FROM test t2
WHERE (t1.a, t1.b) = (t2.b, t2.a) )
Demo
Related
I have a table like this
I want to check the all rows in Column A with column B and get the count of duplicates.
For example, I want to get the
count of 12 as 3(2 times in A+1 time in B)
count of 11 as 2(2 times in A+0 time in B)
count of 13 as 2(1 time in A+0 time in B)
How can I acheive it?
You can calculate the total occurrences from a union all. A where clause can show only the values that occur in the A column:
select nr
, count(*)
from (
select A as nr
from YourTable
union all
select B
from YourTable
) sub
where nr in -- only values that occur at least once in the A column
(
select A
from YourTable
)
group by
nr
having count(*) > 1 -- show only duplicates
You can combine all values in A and B then do the group by.
Then only select those values found in column A.
Select A, count(A) as cnt
From (
Select A
from yourTable
Union All
Select B
from yourTable) t
Where t.A in
(select distinct A from yourTable)
Group by t.A
Order by t.A;
Result:
A cnt
11 2
12 3
13 1
See demo: http://sqlfiddle.com/#!9/9fcfe9/3
I have the following like table
A B
Yes OOS
No No
OOS Yes
OOS No
Yes No
I want to do the following
Criteria A B
Yes 2 1
No 1 3
OOS 2 1
I can get this right with one column like
Criteria A
Yes 2
No 1
OOS 2
Here is what I have to achieve the above:
SELECT A, count(A) FROM temp_db GROUP BY A;
For this sample data, you could do this with a join of derived tables:
SELECT qa.Criteria, qa.A, qb.B FROM
(SELECT A AS Criteria, count(A) AS A FROM temp_db GROUP BY A) qa
FULL OUTER JOIN
(SELECT B AS Criteria, count(B) AS B FROM temp_db GROUP BY B) qb
ON qa.Criteria=qb.Criteria
But if there are missing criteria in the A column, they will not appear in the results of this query, and you would need the UNION ALL approach others have suggested.
You need to get the values into a single column, so you can use group by. Here is one method:
select criteria, sum(A) as A, sum(B) as B
from ((select A as criteria, 1 as A, 0 as B
from liketable
) union all
(select B, 0, 1
from liketable
)
) t
group by criteria;
Using the union all approach is the safest way in MySQL, in case not all criteria are in both columns. The following is a slight tweak that might be a bit better performance-wise:
select criteria, sum(A) as A, sum(B) as B
from ((select A as criteria, count(*) as A, 0 as B
from liketable
group by A
) union all
(select B, 0, count(*)
from liketable
group by B
)
) t
group by criteria;
Often doing two aggregations on half the data is more efficient than a bigger aggregation on all the data.
select val, sum(cntA), sum(cntB)
from (SELECT A as val, count(A) as cntA, 0 as cntB FROM temp_db GROUP BY A;
union all
SELECT B as val, 0 as cntA, count(B) as cntB FROM temp_db GROUP BY B)
group by val;
Why does
select 1 as a, 2 as b
union all
select 20 as b, 10 as a
returns
a b
1 2
20 10
instead of
a b
1 2
10 20
?
Is there a way to make union match column names?
Nope, selecting them in order is required with UNION.
Column names are only pertinent for the first part of the union to deifne the union columns. Other unions will join in the same order the columns are given from the first select and often have differn names. If you want want to relate the first column to the second column, You can't. However you can adjust your second select statment to put the columns in the correct order.
Union only looks at the number of columns, and their relative positions in the query string. it does NOT mix-match based on aliases or the source column names. e.g. You could have two completely different tables:
SELECT x,y FROM foo
UNION
SELECT p,q FROM bar
What should MySQL do in this case? return a single row
x,y,p,q
because none of the column names match? Nope. That'd be incorrect.
I'm not sure if this solves your problem, but you can use subqueries within the union to put the columns in the "right" order:
(select a, b from (select 1 as a, 2 as b) t)
union all
(select a, b from (select 20 as b, 10 as a) t)
I realize the question is tagged MySQL, which doesn't support full outer join. If it did, you could do do the union all as:
select coalesce(t1.a, t2.a) as a, coalesce(t1.b, t2.b) as b
from (select 1 as a, 2 as b) t1 full outer join
(select 20 as b, 10 as a) t2
on 0 = 1;
You can do this in MySQL. This assumes that none of your values are never NULL:
select coalesce(t1.a, t2.a) as a, coalesce(t1.b, t2.b) as b
from (select 1 as a, 2 as b union all select NULL, NULL) t1 join
(select 20 as b, 10 as a union all select NULL, NULL) t2
on (t1.a is null or t2.a is null) and coalesce(t1.a, t2.a) is not null
I have 2 columns as follow:
A | B
---|---
7 | 1
7 | 2
3 | 7
4 | 5
-------
I want to get 1 column containing (1,2,3).
Currently i'm quering this:
SELECT `A` , `B`
FROM `mytable`
WHERE `A` =7
OR `B` =7
but I'm getting 2 columns containing the number 7 in both sides A and B.
i'm sure there is a way to get what I want but I don't know how to google that!!
You could use this:
SELECT
case when A=7 then B else A end
FROM
yourtable
WHERE
7 IN (A, B)
If you want a single column, you could use this:
SELECT
GROUP_CONCAT(case when A=7 then B else A end
ORDER BY case when A=7 then B else A end)
FROM
yourtable
WHERE 7 IN (A, B)
See fiddle here.
If value of both A and B could be 7 at the same time, and you want to skip that row, you could substitute:
WHERE 7 IN (A, B)
with
WHERE A=7 XOR B=7
Not really sure what you need, but I'm guessing something like this:
SELECT A FROM mytable WHERE B=7
UNION
SELECT B FROM mytable WHERE A=7
i think you looking for this
SELECT myresult from (
SELECT A myresult FROM Table1 WHERE A IN (1,2,3)
UNION
SELECT B myresult FROM Table1 WHERE B IN (1,2,3)
)t
ORDER BY myresult
this will out put :
MYRESULT
1
2
3
SQL DEMO HERE
Try this
SELECT A as Single FROM mytable WHERE B=7 UNION
SELECT B as Single FROM mytable WHERE A=7 ORDER BY Single;
If you are expecting result as 1, 2, 3 use below.
SELECT colB as NewCol FROM tableName WHERE colA=7
UNION
SELECT colA as NewCol FROM tableName WHERE colB=7;
If you want both columns simply use
SELECT colA, colB FROM tableName WHERE colA=7 OR colB=7;
Demo at sqlfiddle
you have to try this code..
SELECT b as value FROM users WHERE a='7'
UNION All
SELECT a as value FROM users WHERE b='7'
this query must help you.
Columns a, b and c contain some values of the same nature. I need to select all the unique values. If I had just one column I'd use something like
SELECT DISTINCT a FROM mytable ORDER BY a;
but I need to treat a, b and c columns as one and gett all the unique values ever occurring among them.
As an example, let this be a CSV representation of mytable, the first row naming the columns:
a, b, c
1, 2, 3
1, 3, 4
5, 7, 1
The result of the query is to be:
1
2
3
4
5
7
UPDATE: I don't understand why do all of you suggest wrapping it in an extra SELECT? It seems to me that the answer is
(SELECT `a` AS `result` FROM `mytable`)
UNION (SELECT `b` FROM `mytable`)
UNION (SELECT `c` FROM `mytable`)
ORDER BY `result`;
isn't it?
So you want one column all with unique values from a, b and c? Try this:
(select a as yourField from d1)
union
(select b from d2)
union
(select c from d3)
order by yourField desc
limit 5
Working example
Edited after requirements changed... There you have the order by and limit you requested. Of course, you'll get only 5 records in this example
sorry i miss understood your question. here is updated query.
select a from my table
UNION
select b from my table
UNION
select c from my table
SELECT tmp.a
FROM
(SELECT column_1 AS a
FROM table
UNION
SELECT column_2 AS a
FROM table
UNION
SELECT column_3 AS a
FROM table) AS tmp
ORDER BY `tmp`.`a` ASC
try this:
SELECT b.iResult
FROM
(SELECT a as iResult FROM tableName
UNION
SELECT b as iResult FROM tableName
UNION
SELECT c as iResult FROM tableName) b
ORDER BY b.iResult
LIMIT BY 10 -- or put any number you want to limit.