Determine if columns have duplicate values sql - sql-server

I am trying to figure out a way to check if their is repeated values in rows that are shared.
Example:
HMOID Name Addon10 Addon15 Addon20
RFFF Blah img path1 img path2 img path1
For my example, I would like to check if any of the addons for RFFF have any repeated value. In my example above, 'RFFF' has two images that are the same in Addon10 and Addon20 (The images have a path. so currently, they look like
http://oc2-reatest.regalmed.local/ocupgrade52/images/NDL_SCAN_SR.PNG).
I would like to be able to do this for multiple rows. I thought the following would give me an idea how to begin:
select * from HlthPlan
Group By HMO1A, HMONM
Having COUNT(*) > 1
However, it throughs the following error:
Msg 8120, Level 16, State 1, Line 1
Column 'HlthPlan.HMOID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.*
I am fairly new to SQL and any suggestions would be appreciated.

Don't include * for your select query. Only include the columns that you are using in GROUP BY
SELECT HMO1A, HMONM, COUNT(*) from HlthPlan
GROUP BY HMO1A, HMONM
HAVING COUNT(*) > 1;

With only three columns to check, assuming non-null values across a single row:
select * from HlthPlan
where Addon10 in (Addon15, Addon20) or Addon15 = Addon20
You can also use cross apply to pivot the values for grouping:
select HMOID, addon
from HlthPlan cross apply (
select addon
from (values (Addon01), (Addon02), (Addon03), ... (Addon20)) as pvt(addon)
) a
where addon is not null
group by HMOID, addon
having count(*) > 1;
http://rextester.com/QWIW87618
You'll get multiple rows for each HMOID where the are different groups of columns having the same value. By the way, reporting on the names of specific columns involved would add another degree of difficulty to the query.

One way you can check for this is using UNPIVOT to compare your results:
create table #hmo (hmoid varchar(6), name varchar(25), Addon10 varchar(25),
Addon15 varchar(25), addon20 varchar(25));
insert into #hmo
values ('RFFF', 'Blah','img path1', 'img path2', 'img path1');
select hmoid, name, addval, addcount = count(adds)
FROM #hmo
UNPIVOT
(
addval FOR adds IN
(addon10, addon15, addon20)
) as unpvt
group by hmoid, name, addval having count(*) > 1
Will give results:
hmoid name addval addcount
RFFF Blah img path1 2
This way you can check against every row in the table and will see any row that has any two or more columns with the same value.
This does have the potential to get tedious if you have a lot of columns; the easiest way to correct for that is to build your query dynamically using info from sys.tables and sys.columns.

Related

SQL Server - Replacing NULL values with mode of column grouped by another column

I have a table (call it oldtable) and the relevant columns are name, group, zip code. I have selected those into a new table (call that newtable). My issue is that some of the zip codes in the first table are NULL. I want to replace the NULL zip codes with the mode (most common value) of their group.
For example, say a row in newtable looks like this:
Name Group ZipCode
Blah G1 NULL
I want to replace that NULL with the most common zip code over all the people in G1 in oldtable. I am having trouble even getting started on pulling the mode of one column when grouped by another column.
I am using Microsoft SQL Server 2016.
This can be done using CROSS APPLY on an UPDATE.
UPDATE n SET
zipcode = x.zipcode
FROM newtable n
CROSS APPLY( SELECT TOP 1 zipcode, COUNT(*) cnt
FROM newtable o
WHERE n.[group] = o.[group]
GROUP BY zipcode
ORDER BY cnt DESC) x
WHERE n.zipcode IS NULL;

Pivot / Unpivot the following data

I'm new to Pivots so I'm not exactly sure how I would need to do this.
I have the following data:
I need to pivot/unpivot the above data.
I need the following Columns:
GLLink
AccType
Budget
Budget Value
I've tried developing the code, but I'm afraid I am doing it completely wrong:
select
*
from
(
select
*
from Budgets
) x
unpivot
(
GLLink for Budget in ([AccType])
) p
order by GLLink, Budget
The results I would require should look like this:
Assuming the data you showed us are in a table named 'yourtable', here is the cross apply way:
select t.GLLink,t.Acctype,u.*
from yourtable t
cross apply
(
values
('Budget01',Budget01),
('Budget02',Budget02),
('Budget03',Budget03),
('Budget04',Budget04),
('Budget05',Budget05),
('Budget06',Budget06),
('Budget07',Budget07)
)u(Budget,[Budget Value])
The way it works: cross apply "sees" one row each time. For this row, it uses the values() operator to create a table, so we make the pairs as you need them. In the end, we give a name to this table (u for unpivoted), and also name the columns.
Converting columns to rows is unpivoting (what you need), pivoting is the reverse.

How to join two tables based on Grouping of 1 column in both the tables

I have come up a situation which is not easy to explain in sentence so i will go ahead and give the complete scenario here.
I have one result set like the below :-
It shows header_equipment_id(s) in a group of jil_equipment_id,relationship_name,cell_group.. For example 3159398,4622903 lies in one group.
The other result set is given below, This is the table where i want to update 3 columns namely Is_Applicable_Price,prc_content_rid,prc_type_name
If you notice clearly, You will find the same header_equipment_id column here. If you group it with the result found above, You will find 3 different groups for. But out of those 3 groups, one group is red, It is red because they belong to different cell_group/relationship_name.
**
Yellow and green are passed scenario and Red, Blue are fail.
**
I want to update the columns Is_Applicable_Price,prc_content_rid,prc_type_name if the Group of header_equipment_id(s) fall under the same cell_group and relationship_name.
So the final result set would look something like below -
Please help me with any inputs if possible. It's a situation where i know one single query won't work. But i will need to have multiple Temp tables for the transformation. But this is the shortest i have came across.
I am using Microsoft sql server 2012.
Please help. Even a small hint would be of great help to me. Thanks in advance.
It seems that the only thing the 2 tables have in common is that a cell_group can have a one or more rows of header_equipment_id. If we can generate a unique value based on header_equipment_id then we can join the 2 tables on this value. Note I have used a simple division , you may wish to check that this method is unique enough for your purposes.
/*create table a
(jil_equimentid int,relationship_name varchar(20),header_equipment_id int,
smart_equipment_id int,cell_group int,new_price_flag int,is_applicable_price int,prc_content_rid int,prc_type_name varchar(20))
truncate table a
insert into a values
(1282977,'default',3159398,1282977,3,1,1,106347924,'New Price'),
(1282977,'default',4622903,1262578,3,1,1,106347924,'New Price'),
(1282977,'default',1659861,1282977,6,1,1,106347925,'New Price'),
(1282977,'default',4622904,1282977,6,1,1,106347925,'New Price')
go
drop table t
go
create table t
(jil_equimentid int,relationship_name varchar(20),header_equipment_id int,
smart_equipment_id int,cell_group int,new_price_flag int,is_applicable_price int,prc_content_rid int,prc_type_name varchar(20))
truncate table t
insert into t values
(1282977,'128297711111 default',4622903,1282977,1,1,null,null,null),
(1282977,'128297711211 default',3159398,1262578,2,1,null,null,null),
(1282977,'128297712111 default',4622904,1282977,4,1,null,null,null),
(1282977,'128297712211 default',1659861,1282977,5,1,null,null,null),
(1282977,'128297711101 default',3159398,1262578,1,1,null,null,null),
(1282977,'128297711101 default',4622903,1282977,1,1,null,null,null),
(1282977,'default' ,3159398,1262578,2,1,null,null,null),
(1282977,'default' ,4622903,1282977,2,1,null,null,null),
(1282977,'128297711101 default',1659861,1262577,3,1,null,null,null),
(1282977,'128297711101 default',4622904,1282977,3,1,null,null,null),
(1282977,'default' ,1659861,1262577,4,1,null,null,null),
(1282977,'default' ,4622904,1262577,4,1,null,null,null)
*/
DROP TABLE #TEMPA;
;WITH CTE AS
(SELECT a.cell_group,
sum(a.header_equipment_id / 10000000.0000) uniqueval
from a
group by a.cell_group
)
SELECT DISTINCT CTE.UNIQUEVAL ,IS_APPLICABLE_PRICE ,PRC_CONTENT_RID ,PRC_TYPE_NAME
INTO #TEMPA
FROM CTE
JOIN A ON A.CELL_GROUP = CTE.CELL_GROUP
;WITH CTE AS
(
SELECT t.relationship_name,t.cell_group,
sum(t.header_equipment_id / 10000000.0000) uniqueval
from t
group by t.relationship_name,t.cell_group having count(*) > 1
)
SELECT T.*,CTE.UNIQUEVAL,ta.*
FROM CTE
JOIN T ON T.RELATIONSHIP_NAME = CTE.RELATIONSHIP_NAME AND T.CELL_GROUP = CTE.CELL_GROUP
join #tempa ta on ta.uniqueval = cte.uniqueval

Solving Duplicated in Access

i had a table depends on more than one tables and i get this final
ScrrenShoot have a look in picture
i need to choose from values if firstdate duplicated in specific criteria
for ex . i need one row for 18.2.2016 / max value ( get the greater one ) / min value (get the less one )
You need to provide us with better information, but here is what I think you're looking for.
You need a separate query for each min/max value you want to find. Where you see "MyTable" you need to replace it with the object name shown in the screenshot.
Query 1 "Max"
SELECT MyTable.FirstOfDate, Max(MyTable.MaxValue) AS MaxOfMaxValue
FROM MyTable
GROUP BY MyTable.FirstOfDate;
Query 2 "Min"
SELECT MyTable.FirstOfDate, Min(MyTable.MinValue) AS MinOfMinValue
FROM MyTable
GROUP BY MyTable.FirstOfDate;
Query 3 "Merge"
SELECT DISTINCT MyTable.FirstOfDate, Max.MaxOfMaxValue, Min.MinOfMinValue
FROM (MyTable
INNER JOIN [Max] ON MyTable.FirstOfDate = Max.FirstOfDate)
INNER JOIN [Min] ON MyTable.FirstOfDate = Min.FirstOfDate
GROUP BY MyTable.FirstOfDate, Max.MaxOfMaxValue, Min.MinOfMinValue;

How can we add a column on the fly in a dynamic table in SQL SERVER?

My question needs little explanation so I'd like to explain this way:
I've got a table (lets call it RootTable), it has one million records, and not in any proper order. What I'm trying to do is to get number of rows(#ParamCount) from RootTable and at the same time these records must be sorted and also have an additional column(with unique data) added on the fly to maintain a key for row identification which will be used later in the program. It can take any number of parameters but my basic parameters are the two which mentioned below.
It's needed for SQL SERVER environment.
e.g.
RootTable
ColumnA ColumnB ColumnC
ABC city cellnumber
ZZC city1 cellnumber
BCD city2 cellnumber
BCC city3 cellnumber
Passing number of rows to return #ParamCount and columnA startswith
#paramNameStartsWith
<b>#paramCount:2 <br>
#ParamNameStartsWith:BC</b>
desired result:
Id(added on the fly) ColumnA ColumnB ColumnC
101 BCC city3 cellnumber
102 BCD city2 cellnumber
Here's another point about Id column. Id must maintain its order, like in the above result it's starting from 101 because 100 is already assigned to the first row when sorted and added column on the fly, and because it starts with "ABC" so obviously it won't be in the result set.
Any kind of help would be appreciated.
NOTE: My question title might not reflect my requirement, but I couldn't get any other title.
So first you need your on-the-fly-ID. This one is created by the ROW_NUMBER() function which is available from SQL Server 2005 onwards. What ROW_NUMBER() will do is pretty self-explaining i think. However it works only on a partition. The Partition is specified by the OVER clause. If you include GROUP BY within the OVER clause, you will have multiple partitions. In your case, there is only one partition which is the whole table, therefor GROUP BY is not necessary. However an ORDER BY is required so that the system knows which record should get which row number in the partition. The query you get is:
SELECT ROW_NUMBER() OVER (ORDER BY ColumnA) ID, ColumnA,ColumnB,ColumnC
FROM RootTable
Now you have a row number for your whole table. You cannot include any condition like your #ParamNameStartsWith parameter here because you wanted a row number set for the whole table. The query above has to be a subquery which provides the set on which the condition can be applied. I use a CTE here, i think that is better for readability:
;WITH OrderedList AS (
SELECT ROW_NUMBER() OVER (ORDER BY ColumnA) ID, ColumnA,ColumnB,ColumnC
FROM RootTable
)
SELECT *
FROM OrderedList
WHERE ColumnA LIKE #ParamNameStartsWith+'%'
Please note that i added the wildcard % after the parameter, so that the condition is basically "starts with" #ParamNameStartsWith.
Finally,if i got you right you wanted only #ParamCount rows. You can use your parameter directly with the TOP keyword which is also only possible with SQL Server 2005 or later.
;WITH OrderedList AS (
SELECT ROW_NUMBER() OVER (ORDER BY ColumnA) ID, ColumnA,ColumnB,ColumnC
FROM RootTable
)
SELECT TOP (#ParamCount) *
FROM OrderedList
WHERE ColumnA LIKE #ParamNameStartsWith+'%'

Resources