Sample 3 random rows then order them alphabetically by another property - sql

I was just wondering if I can get three random results and then order them by another column alphabetically.
Example:
SELECT TOP(3)[Name]
FROM Table
ORDER BY NEWID()
¿ORDER BY [Surname]?
Thanks in advance.

Not sure to understand the problem at 100%, but with a second ORDER BY it will sort all of the differents ID.
I did a CTE for achieving this result.
WITH CTE AS
(
SELECT TOP(3)[Name]
FROM Table
ORDER BY NEWID()
)
SELECT *
FROM CTE
ORDER BY [Surname]

Have a derived table (sub-query) where you select 3 random rows. ORDER BY its result.
select [Name]
from
(
SELECT TOP(3) [Name], [Surname]
FROM Table
ORDER BY NEWID()
) dt
ORDER BY [Surname]

You can try this.
SELECT T.*
FROM
(
SELECT TOP(3)[Name], [Surname]
FROM Table
ORDER BY NEWID()
) AS T
ORDER BY [Surname];

you can try this -
declare #name table
(Name varchar(20), SurName varchar(20))
insert into #name
values
('mukesh', 'arora'),
('amit', 'kumar'),
('Vijay', 'gupta'),
('jai', 'poddar'),
('vishal', 'sharma')
select Name from
(
SELECT TOP(3)[Name] , [Surname]
FROM #name
ORDER BY NEWID()
) a
ORDER BY [Surname]

Related

Improve SQL Query to find redundant data

the following shows my sample dataset
PatientID PatientName
XXX-037070002 Riger, Jens^Wicki
XXX-037070002 Riger^Wicki
XXX-10052 Weier,Nicole^Peggy
XXX-10052 Weier,Nicole^Peppy
XXX-23310 Rodem^Sieglinde
XXX-23310 Sauberger, Birgit^Finja
XXX-23343 Je, Ronny^Wilma
XXX-23343 Jer, Ronny^Wilma
XXX-2349 Kel,Andy^Juka
XXX-2349 Kel^Juka
XXX-2998 Hel, Frank
XXX-2998 Hel,Frank^Fenris
XXX-3188 Mey, Marion
XXX-3188 Mey, Marion^Paula
XXX-3188 Schulz^Roma
XXX-3218 Böntgen-Simnet,Dr. Regine^Cara
XXX-3218 Simnet,Dr. Regine^Cara
XXX-3826 Mertes, Bernd Uwe^Ellie
XXX-3826 Mertes,Bernd^Ellie
XXX-3826 Mertes^Ellie
This is the query I got from my last request:
with d as
(
select distinct
patid,
patname
from dicomstudys
)
select *
from d
where d.patid in
(
select d.patid
from d
group by d.patid
having count(*) > 1
)
Now I want to adjust the query that only the following data get's an output:
PatientID PatientName
XXX-23310 Rodem^Sieglinde
XXX-23310 Sauberger, Birgit^Finja
XXX-23343 Je, Ronny^Wilma
XXX-23343 Jer, Ronny^Wilma
XXX-3188 Mey, Marion
XXX-3188 Mey, Marion^Paula
XXX-3188 Schulz^Roma
XXX-3218 Böntgen-Simnet,Dr. Regine^Cara
XXX-3218 Simnet,Dr. Regine^Cara
Last names are either seperated with a ',' or '^' . If last names are the same for the same PatientID then I dont want them being displayed. I tried fiddling with a sub select statement featuring a combination of CHARINDEX commands and others but my SQL syntax knowledge is very limited with the complexity of the request.
Please also note that for the case for XXX-3188 has two datasets with the same last name but also another dataset with a complete new patientName and thus it needs to be in the output.
Try this:
DECLARE #DataSource TABLE
(
[ID] VARCHAR(32)
,[Name] VARCHAR(256)
);
INSERT INTO #DataSource ([ID], [Name])
VALUES ('XXX-037070002', 'Riger, Jens^Wicki')
,('XXX-037070002', 'Riger^Wicki')
,('XXX-10052', 'Weier,Nicole^Peggy')
,('XXX-10052', 'Weier,Nicole^Peppy')
,('XXX-23310', 'Rodem^Sieglinde')
,('XXX-23310', 'Sauberger, Birgit^Finja')
,('XXX-23343', 'Je, Ronny^Wilma')
,('XXX-23343', 'Jer, Ronny^Wilma')
,('XXX-2349', 'Kel,Andy^Juka')
,('XXX-2349', 'Kel^Juka')
,('XXX-2998', 'Hel, Frank')
,('XXX-2998', 'Hel,Frank^Fenris')
,('XXX-3188', 'Mey, Marion')
,('XXX-3188', 'Mey, Marion^Paula')
,('XXX-3188', 'Schulz^Roma')
,('XXX-3218', 'Böntgen-Simnet,Dr. Regine^Cara')
,('XXX-3218', 'Simnet,Dr. Regine^Cara')
,('XXX-3826', 'Mertes, Bernd Uwe^Ellie')
,('XXX-3826', 'Mertes,Bernd^Ellie')
,('XXX-3826', 'Mertes^Ellie');
WITH DataSource AS
(
SELECT [ID]
,[Name]
,COUNT(*) OVER (PARTITION BY [ID], LTRIM(RTRIM(SUBSTRING([Name], 0, CHARINDEX(',', REPLACE([Name], '^', ',')))))) AS [ID_Name_Count]
,COUNT(*) OVER (PARTITION BY [ID]) AS [ID_Count]
,LTRIM(RTRIM(SUBSTRING([Name], 0, CHARINDEX(',', REPLACE([Name], '^', ','))))) AS [FamilyName]
FROM #DataSource
)
SELECT [ID]
,[Name]
FROM DataSource
WHERE [ID_Name_Count] = 1
AND [ID_Count] = 2
OR [ID] IN
(
SELECT [ID]
FROM DataSource
GROUP BY [ID]
HAVING COUNT(DISTINCT [FamilyName]) > 1
);
Тhe solution is pretty easy. Here are the interesting parts:
replace the ^ with , in order to simplify the last name extraction
extract the last name and calculation count based on ID and last name
in the final select check for unique id-last name pairs with id count equal to 2 and add ids with more then one unique family names (your special case)
You can try something like that:
Test data
drop table if exists #Patient;
create table #Patient (
PatientID varchar(20),
PatientName varchar(50)
);
insert into #Patient(PatientID,PatientName)
values ('XXX-037070002' ,'Riger, Jens^Wicki'),
('XXX-037070002' ,'Riger^Wicki'),
('XXX-10052' ,'Weier,Nicole^Peggy'),
('XXX-10052' ,'Weier,Nicole^Peppy'),
('XXX-23310' ,'Rodem^Sieglinde'),
('XXX-23310' ,'Sauberger, Birgit^Finja'),
('XXX-23343' ,'Je, Ronny^Wilma'),
('XXX-23343' ,'Jer, Ronny^Wilma'),
('XXX-2349' ,'Kel,Andy^Juka'),
('XXX-2349' ,'Kel^Juka'),
('XXX-2998' ,'Hel, Frank'),
('XXX-2998' ,'Hel,Frank^Fenris'),
('XXX-3188' ,'Mey, Marion'),
('XXX-3188' ,'Mey, Marion^Paula'),
('XXX-3188' ,'Schulz^Roma'),
('XXX-3218' ,'Böntgen-Simnet,Dr. Regine^Cara'),
('XXX-3218' ,'Simnet,Dr. Regine^Cara'),
('XXX-3826' ,'Mertes, Bernd Uwe^Ellie'),
('XXX-3826' ,'Mertes,Bernd^Ellie'),
('XXX-3826' ,'Mertes^Ellie');
My solution
with q1 as (
select
PatientID,
PatientName,
case when CHARINDEX(',',REPLACE( PatientName, '^',',')) > 0
then LEFT(PatientName,CHARINDEX(',',REPLACE( PatientName, '^',','))-1)
else PatientName end as FullName
from #Patient
) ,
q2 as (
select PatientID
from q1
group by PatientID having COUNT(1) > 1 and COUNT(DISTINCT FullName) > 1 )
select t.PatientID,t.PatientName
from #Patient t join q2 on t.PatientID = q2.PatientID;

Subquery returned more than 1 value while inserting statement with multiple select statements

When I try to run the insert statement with multiple select statements, I am getting error
Msg 512, Level 16, State 1, Line 3 Subquery returned more than 1
value. This is not permitted when the subquery follows =, !=, <, <= ,>, >= or when the subquery is used as an expression. The statement has been terminated.
My query
insert into zzz_fkp_tbl2 (fname,lname) values
(
(select top 20 percent [FNAME] from ZZZ_FKP_NEW_PATIENT order by newid())
,(select top 20 percent lname from ZZZ_FKP_NEW_PATIENT order by newid())
);
But when I run the insert statement with single statement, this query is runnig successfully, like:
insert into zzz_fkp_tbl2 (lname)
select top 20 percent lname from ZZZ_FKP_NEW_PATIENT order by newid();
Why I am getting error Subquery returned more than 1 value while using multiple select statements. But the insert statement is working fine with single select statement. How can I use multiple select statements in this case?
My requirement is to select separate random rows for fname and lname, but not together i.e. fname should be selected randomly and lname should be selected randomly.
target table
create table zzz_fkp_tbl2
(
zzz_fkp_tbl2_id int identity(1,1) not null
,name varchar(200)
,fname varchar(200)
,lname varchar(200)
,gender int
,address int
,age varchar(10)
);
You are looking for this
INSERT INTO zzz_fkp_tbl2
(fname,
lname)
SELECT TOP 20 PERCENT [FNAME],
lname
FROM ZZZ_FKP_NEW_PATIENT
ORDER BY Newid()
Update :
SELECT TOP 20 PERCENT a.FNAME,
b.lname
FROM ZZZ_FKP_NEW_PATIENT
OUTER apply (SELECT TOP 1 [FNAME] ZZZ_FKP_NEW_PATIENT
ORDER BY Newid()) a ([FNAME])
OUTER apply (SELECT TOP 1 lname ZZZ_FKP_NEW_PATIENT
ORDER BY Newid()) b (lname)
insert into zzz_fkp_tbl2 (fname,lname) values
(
(select top(1) [FNAME] from ZZZ_FKP_NEW_PATIENT order by newid())
,(select top(1) lname from ZZZ_FKP_NEW_PATIENT order by newid())
);

Insert into table from another table after sorting data of first table

I am doing something like this in SP,
insert into #FilteredTbl select * from #MasterTbl
but now problem is that i want data of #MasterTbl sorted before adding into #FilteredTbl,
How can I do that ?
Maybe something like this:
INSERT INTO #FilteredTbl
SELECT * FROM #MasterTbl AS tbl
ORDER BY tbl.OrderbyColumn
Try following method to insert sort result into temp table. Use ROW_NUMBER to ORDER BY table result
DECLARE #FilteredTbl AS TABLE
(
RowID INT
[Column_1]
[Column_2]
.
.
)
insert into #FilteredTbl
select ROW_NUMBER()OVER(ORDER BY [ShortColumn]),[Field_1],[Field_2]... from #MasterTbl
You can use order by class in select statement
insert into #FilteredTbl
select * from #MasterTbl
order by <column name>
INSERT INTO #FilteredTbl SELECT * FROM #MasterTbl AS mtb ORDER BY mtb.OrderbyColumn [desc]
Here desc is optional if you want to order by your column in descending order than add ir otherwise no need to add
Please sort the table as you want before inserting into another table.
Like:
Select * From #MasterTbl m Order By m.ColumnName
then insert into your new table
Insert Into #FilterTbl Select * From #MasterTbl m Order By m.ColumnName [DESC]
You can also filter your #MasterTbl using Where Clause
You should add identity your table then It will sorted like that
CREATE TABLE #test (
s int IDENTITY (1, 1),
ID int,
Name varchar(50),
part int
);
INSERT INTO #test (ID,Name,Part)
SELECT ID, Name, Part FROM Table_1 ORDER BY ID DESC
SELECT * FROM #test

SQL Select Counter by Group

Here is the code I've written to create a scenario:
USE tempdb
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'dbo.Emp') AND type in (N'U'))
DROP TABLE Emp
GO
CREATE TABLE Emp(
EmpID Int Identity(10,1) Primary Key,
EmpGroupID Int)
GO
INSERT INTO Emp(EmpGroupID) VALUES(1000)
INSERT INTO Emp(EmpGroupID) VALUES(1000)
INSERT INTO Emp(EmpGroupID) VALUES(1000)
INSERT INTO Emp(EmpGroupID) VALUES(2000)
INSERT INTO Emp(EmpGroupID) VALUES(2000)
INSERT INTO Emp(EmpGroupID) VALUES(2000)
INSERT INTO Emp(EmpGroupID) VALUES(3000)
GO
SELECT * FROM Emp
ORDER BY EmpGroupID,EmpID
What I need is for each group to have a counter variable, incrementing by 1, such that all the rows for Group 1000 have counter=1, groupid=2000 has counter=2, groupid=3000 has counter=3.
SELECT ?,EmpID,EmpGroupID
FROM Emp
ORDER BY EmpGroupID,EmpID
-- The result I'm looking for is:
1,10,1000
1,11,1000
1,12,1000
2,13,2000
2,14,2000
2,15,2000
3,16,3000
You're describing a dense ranking of groups:
SELECT
DENSE_RANK() OVER (ORDER BY EmpGroupID) as Counter,
EmpID,
EmpGroupID
FROM Emp
ORDER BY EmpGroupID,EmpID
And here's some reference material: http://msdn.microsoft.com/en-us/library/ms189798.aspx
You mean, you need a query that produces textual output with the commas as shown?
Try:
SELECT Counter + ',' + EmpGroupID + ',' + EmpID
FROM Table
ORDER BY EmpGroupID
ORDER BY can have more than one clause
Try
SELECT Counter,EmpGroupID, EmpID
ORDER BY Counter,EmpGroupID, EmpID
Guessing from your description, do you want something like
SELECT EmpGroupID, EmpID, COUNT(1) AS Counter
FROM some-table-name
GROUP BY EmpGroupID, EmpID
ORDER BY COUNT(1), EmpGroupID, EmpID
That's for SQL Server - in other cases you may be able to say
ORDER BY Counter, EmpGroupID, EmpID
It took me a while to understand what you were asking. As I understand it, you want to create and populate the 'Counter' column based on the EmpGroupID? If so, then something like this:
SELECT EmpGroupID, EmpID,
(SELECT COUNT(*) +1
FROM [table]
WHERE t2.EmpGroupID < t1.EmpGroupID GROUP BY t2.EmpGroupID
) AS Counter
FROM [table] t1
ORDER BY EmpGroupID, EmpID
Try this:
SELECT DENSE_RANK() OVER (ORDER BY EmpID) as 'counter',GroupID
FROM Emp
ORDER BY counter, EmpGroupID

Pivot String SQL

I am trying to Pivot this table whose name is #salida
IDJOB NAME DATE
1 Michael NULL
1 Aaron NULl
THe result which I want to obtain is
IDJOB DATE NAME1 NAME2
1 NULL Michael Aaron
My code is this
SELECT *
FROM #salida
PIVOT
(
MAX([Name]) FOR [Name] IN ([Name1],[Name2])
) PVT GROUP BY IdJob,Date,Name1,Name2 ;
SELECT * FROM #salida
The result which obtain is
IDJOB DATE NAME1 NAME2
1 NULL NULL NULL
#XabiIparra, see a mock up. you need to partition by the IdJob and then add the columns needed.
DECLARE #salida TABLE(idjob VARCHAR(100),[Name] VARCHAR(100),[DATE] DATE);
INSERT INTO #salida VALUES
(1,'Michael', NULL)
,(1,'Aaron', NULL)
,(2,'Banabas', NULL)
SELECT p.*
FROM
(
SELECT *
,'NAME'+CAST(ROW_NUMBER() OVER(PARTITION BY [idjob] ORDER BY NAME) AS varchar(100)) ColumnName
FROM #salida
)t
PIVOT
(
MAX([Name]) FOR ColumnName IN (NAME1,NAME2,NAME3,NAME4,NAME5 /*add as many as you need*/)
)p;
How about must using aggregation and min() and max()?
select idjob, date, min(name), max(name)
from #salida
group by idjob, date;
SQL tables represent unordered sets, so there is no ordering to the values (unless another column specifies the ordering). So, this is probably the simplest way to get two different values in the same row.