Reputation: 342
How to verify the number of unique values in the columns? For example I have a table:
Shop_1 | Shop_2 | Shop_3 | Shop_4 |
---|---|---|---|
Adidas | Nike | Adidas | |
Reebok | Nike | Adidas | Asics |
Ascics | Asics | Asics | Asics |
Nike | Nike | Nike | Adidas |
For this table, I would like to have an additional column with information on how many unique stores appeared in a given record. The results should be as follows:
CREATE TABLE shops
(ID INTEGER PRIMARY KEY,
shop1 CHAR(20),
shop2 CHAR(20),
shop3 CHAR(20),
shop4 CHAR(20),
expected_result INT )
INSERT INTO shops VALUES (1, 'Adidas', 'Nike', 'Adidas', null, 2);
INSERT INTO shops VALUES (2, 'Reebok', 'Nike', 'Adidas', 'Asics', 4);
INSERT INTO shops VALUES (3, 'Asics', 'Asics', 'Asics', 'Asics', 1);
INSERT INTO shops VALUES (4, 'Nike', 'Nike', 'Nike', 'Adidas', 2);
Upvotes: 0
Views: 181
Reputation: 22167
PLease try the following method.
SQL #1
-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, Shop_1 VARCHAR(20), Shop_2 VARCHAR(20), Shop_3 VARCHAR(20), Shop_4 VARCHAR(20));
INSERT INTO @tbl (Shop_1, Shop_2, Shop_3, Shop_4) VALUES
('Adidas', 'Nike', 'Adidas', NULL),
('Reebok', 'Nike', 'Adidas', 'Asics'),
('Asics', 'Asics', 'Asics', 'Asics'),
('Nike', 'Nike', 'Nike', 'Adidas');
-- DDL and sample data population, end
SELECT *
, (
SELECT Shop_1, Shop_2, Shop_3, Shop_4
FOR XML PATH(''), TYPE, ROOT('root')
)
.value('count(distinct-values(/root/*/text()))','INT') AS [Counter]
FROM @tbl AS p;
SQL #2
It allows to handle a scenario where column list is vary: Shop_1, Shop_2, ..., ShopN.
SELECT *
, (
SELECT *
FROM @tbl AS c
WHERE c.ID = p.ID
FOR XML PATH(''), TYPE, ROOT('root')
)
.value('count(distinct-values(/root/*[local-name()!="ID"]/text()))','INT') AS [UniqueCounter]
FROM @tbl AS p;
Output
+----+--------+--------+--------+--------+---------+
| ID | Shop_1 | Shop_2 | Shop_3 | Shop_4 | Counter |
+----+--------+--------+--------+--------+---------+
| 1 | Adidas | Nike | Adidas | NULL | 2 |
| 2 | Reebok | Nike | Adidas | Asics | 4 |
| 3 | Asics | Asics | Asics | Asics | 1 |
| 4 | Nike | Nike | Nike | Adidas | 2 |
+----+--------+--------+--------+--------+---------+
Upvotes: 2
Reputation: 65218
A dynamical solution might be by using a catalog table(information_schema.columns
) such as
DECLARE @cols1 AS NVARCHAR(MAX), @cols2 AS NVARCHAR(MAX), @query AS NVARCHAR(MAX)
SET @cols1 = ( SELECT STRING_AGG(QUOTENAME([column_name]),',')
FROM information_schema.columns
WHERE [column_name] != 'ID'
AND [table_name]='shops');
SET @cols2 = ( SELECT STRING_AGG('COUNT('+QUOTENAME([column_name])+')
OVER (PARTITION BY ID ORDER BY ID)','+') AS total
FROM information_schema.columns
WHERE [column_name] != 'ID');
SET @query = N'SELECT [ID], '+ @cols1 +',' + @cols2 +
N' FROM [shops]';
--SELECT @query;
EXEC sp_executesql @query;
Upvotes: 1
Reputation: 32579
One way you can do this would be to use cross apply
to pivot and then count
select *
from #t
cross apply (
select Count (distinct shops) UniqueCount
from (
values (shop_1),(shop_2),(shop_3),(shop_4)
)x(shops)
)a
Upvotes: 2
Reputation: 824
Just count the distinct values for the columns.
SELECT
COUNT(DISTINCT shop_1) count1,
COUNT(DISTINCT shop_2) count2,
COUNT(DISTINCT shop_3) count3,
COUNT(DISTINCT shop_4) count4
FROM
your_table
Upvotes: -1