I have a table with col A and col B. Col A and Col B can have repetitive values.
I want to select distinct values from Col A and Col B individually and populate them in 1 column as unique values. How do I do that?
Example
col_a | col_b
------+------
1 | 3
2 | 4
3 | 5
4 | 7
5 | 8
6 |
I want to extract the total unique values in a table that says 1,2,3,4,5,6,7,8. How do I do that?
You can use a UNION to combine two results with each column. A UNION will remove duplicates automatically:
select col_a as value
from the_table
union
select col_b
from the_table;
One simple approach is to use a union:
SELECT DISTINCT val
FROM
(
SELECT A AS val FROM yourTable
UNION ALL
SELECT B FROM yourTable
) t;
Demo
Related
I have a table that looks like this. And I want to get the distinct count horizontally across the three columns ignoring nulls.
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
One possible option would be
WITH sample AS (
SELECT 'A' Column1, 'B' Column2, 'C' Column3 UNION ALL
SELECT 'A', 'A', 'B' UNION ALL
SELECT 'A', 'A', NULL UNION ALL
SELECT '', 'A', NULL
)
SELECT Column1, Column2, Column3, COUNT(DISTINCT NULLIF(TRIM(c), '')) unique_count
FROM (SELECT *, ROW_NUMBER() OVER () rn FROM sample) t LATERAL VIEW EXPLODE(ARRAY(Column1, Column2, Column3)) tf AS c
GROUP BY Column1, Column2, Column3, rn;
output
+---------+---------+---------+--------------+
| column1 | column2 | column3 | unique_count |
+---------+---------+---------+--------------+
| | A | NULL | 1 |
| A | A | NULL | 1 |
| A | A | B | 2 |
| A | B | C | 3 |
+---------+---------+---------+--------------+
case when C1 not in (C2, C3) then 1 else 0 end +
case when C2 not in (C3) then 1 else 0 end + 1
This will not work if you intend to count nulls. The pattern would extend to more columns by successively comparing each one to all columns to its right. The order doesn't strictly matter. There's just no point in repeating the same test over and over.
If the values were alphabetically ordered then you could test only adjacent pairs to look for differences. While that applies to your limited sample it would not be the most general case.
Using a column pivot with a distinct count aggregate is likely to be a lot less efficient, less portable, and a lot less adaptable to a broad range of queries.
Consider the below table:
Table1
id | status
------------
1 | A
2 | B
3 | C
1 | B
4 | B
5 | C
4 | A
Desired output is 1 and 4 as they are having status as both 'A' and 'B'.
Can we write an query for this? I tried to query it using conditions like 'AND', 'UNION' and 'OR', but it did not return me the desired result.
If you want the ids with more than 1 statuses:
select id
from tablename
group by id
having count(distinct status) > 1
You can use aggregation:
select id
from t
where status in ('A', 'B')
group by id
having count(*) = 2;
If the table allows duplicates, then use count(distinct status) = 2.
Try this one, you can do without using having() as well
select
id
from
(
select
id,
count(distinct status) as cnt
from yourTable
group by
id
) val
where cnt > 1
Say I have a table like this:
column1 | column2
---------------------
1 | a
1 | b
1 | c
2 | a
2 | b
I need an SQL query to show the distinct values from column 1, and a count of the related distinct values from column 2. The output would look like:
column1 | count
-------------------
1 | 3
2 | 2
You could do something like this:
SELECT column1, count(column2)
FROM table
GROUP BY column1
You should do a COUNT(DISTINCT ...) with a GROUP BY:
Select Column1,
Count(Distinct Column2) As Count
From Table
Group By Column1
I have a table T, say
1 | a
2 | a
I want to duplicate its rows while changing the value of the second column to b, so as to have
1 | a
2 | a
1 | b
2 | b
I came to
INSERT INTO T(col1, col2)
SELECT col1, 'b'
FROM T
but I get an error
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
Remove those extra parentheses in the SELECT :
INSERT INTO T(col1, col2)
SELECT col1, 'b' AS col2 FROM T;
I have a query that as the following rows:
Id | key | Value
1 Type.name.1 Value1
2 Type.name.2 Value2
3 Type.desc.1 Desc1
4 Type.desc.2 Desc2
And I need a query that returns this:
Type.NameId | Type.DescId
1 3
2 4
How can I do this in Postgres?
SELECT *
FROM (
SELECT right(key, -10) AS name_id
WHERE "value" ~~ 'Value%'
) n
FULL JOIN (
SELECT right(key, -10) AS name_id, id AS desc_id
WHERE "value" ~~ 'Desc%'
) d USING name_id;
Exact form depends on a lot of details missing in your question.
Your table design and naming convention give me the shivers.