I have table as below.
Name Primary phone Primary Ind
Manju 11 Y
Manju 22 N
Tyagi 33 N
Tyagi 44 Y
And I want my result to be displayed like below based on the Primary Ind Flag in my table above. Basically if the primary indicator is "Y" Phone No should go to 'Primary Phone`. IF "N", it should go to "Non Primary"
Name Primary Phone Non Primary
manju 11 22
Tyagi 44 33
I need to achieve this using select and UNION. this is the assignment gave to me. Can somebody help how to do it?
A self join
select t1.name, t1.phone as primary, t2.phone as non
from table t1
join table t2
on t2.name = t1.name
and t1.ind = 'y'
and t2.ind = 'n'
Not the way I'd handle this but as it's the requirement:
Simply generate two sets of data one with Y one with N, union and get the max of each. That max assumes that each record only has 2 phone #'s (one each primary & non-Primary)
SELECT name
, max([Primary Phone]) as [Primary Phone]
, max([non Primary] as [Non Primary)
FROM (SELECT name, [Primary phone], null as [non Primary]
FROM TABLE
WHERE [Primary Ind] = 'Y'
UNION ALL
SELECT name, Null as [Primary Phone], [Primary Phone ]
FROM TABLE
WHERE [Primary Ind] = 'N') DT
GROUP BY name
Union vs union all depends on if you have duplicates you need to eliminate, if you know you don't union all is slightly faster.
Union is not necessary but still you need it ,
select name,primaryphone,nonprimary from (
select name,primaryphone
from
(
select name,primaryphone,'primary' PrimaryInd from yourtable where primaryind='Y'
union
select name,primaryphone,'non primary' from yourtable where primaryind='N'
) a
where primaryind='primary')a1 join
( select name as name1,primaryphone as nonprimary
from
(
select name,primaryphone,'primary' PrimaryInd from yourtable where primaryind='Y'
union
select name,primaryphone,'non primary' from yourtable where primaryind='N'
) a
where primaryind='non primary')a2
on a1.name=a2.name1
check this-http://sqlfiddle.com/#!18/5a8db/23
Related
I have the below records in my table,
If the HoleNumber combination is not having 'A' and 'B' for the particular datetime, we need to remove the alphabets from the number.
i.e., Remove 'A' from third record and sixth record. Because, it doesn't have B combinations for that datetime.
delete from myTable
where id in
(
select id from myTable t1
inner join
(
select [date], left([holeNumber], len(holeNumber)-1) as hNumber
from myTable
group by [date], left([holeNumber], len(holeNumber)-1)
having count(holeNumber) = 1
) tmp
on t1.[date] = tmp.[date] and left(t1.holeNumber, len(holeNumber)-1) = tmp.hNumber);
would do it, provided your requirements are strictly to remove having only 1 type of holeNumber.
DBFiddle demo
I do have following table
ID Name
1 Jagan Mohan Reddy868
2 Jagan Mohan Reddy869
3 Jagan Mohan Reddy
Name column size is VARCHAR(55).
Now for some other task we need to take only 10 varchar length i.e. VARCHAR(10).
My requirement is to check that after taking the only 10 bits length of Name column value for eg if i take Name value of ID 1 i.e. Jagan Mohan Reddy868 by SUBSTRING(Name, 0,11) if it equals with another row value. here in this case the final value of SUBSTRING(Jagan Mohan Reddy868, 0,11) is equal to Name value of ID 3 row whose Name is 'Jagan Mohan Reddy'. I need to make a list of those kind rows. Can somebody help me out on how can i achieve in SQL Server.
My main check is that the truncated values of my Name column should not match with any non truncated values of Name column. If so i need to get those records.
Assuming I understand the question, I think you are looking for something like this:
Create and populate sample data (Please save us this step in your future questions)
DECLARE #T as TABLE
(
Id int identity(1,1),
Name varchar(15)
)
INSERT INTO #T VALUES
('Hi, I am Zohar.'),
('Hi, I am Peled.'),
('Hi, I am Z'),
('I''m Zohar peled')
Use a cte with a self inner join to get the list of ids that match the first 10 chars:
;WITH cte as
(
SELECT T2.Id As Id1, T1.Id As Id2
FROM #T T1
INNER JOIN #T T2 ON LEFT(T1.Name, 10) = t2.Name AND T1.Id <> T2.Id
)
Select the records from the original table, inner joined with a union of the Id1 and Id2 from the cte:
SELECT T.Id, Name
FROM #T T
INNER JOIN
(
SELECT Id1 As Id
FROM CTE
UNION
SELECT Id2
FROM CTE
) U ON T.Id = U.Id
Results:
Id Name
----------- ---------------
1 Hi, I am Zohar.
3 Hi, I am Z
Try this
SELECT Id,Name
FROM(
SELECT *,ROW_NUMBER() OVER(PARTITION BY Name, LEFT(Name,11) ORDER BY ID) RN
FROM Tbale1 T
) Tmp
WHERE Tmp.RN = 1
loop over your column for all the values and put your substring() function inside this loop and I think in Sql index of string starts from 1 instead of 0. If you pass your string to charindex() like this
CHARINDEX('Y', 'Your String')
thus you will come to know whether it is starting from 0 or 1
and you can save your substring value as value of other column with length 10
I hope it will help you..
I think this should cover all the cases you are looking for.
-- Create Table
DECLARE #T as TABLE
(
Id int identity(1,1),
Name varchar(55)
)
-- Create Data
INSERT INTO #T VALUES
('Jagan Mohan Reddy868'),
('Jagan Mohan Reddy869'),
('Jagan Mohan Reddy'),
('Mohan Reddy'),
('Mohan Reddy123551'),
('Mohan R')
-- Get Matching Items
select *, SUBSTRING(name, 0, 11) as ShorterName
from #T
where SUBSTRING(name, 0, 11) in
(
-- get all shortnames with a count > 1
select SUBSTRING(name, 0, 11) as ShortName
from #T
group by SUBSTRING(name, 0, 11)
having COUNT(*) > 1
)
order by Name, LEN(Name)
I have this tables:
tblDiving(
diving_number int primary key
diving_club int
date_of_diving date)
tblDivingClub(
number int primary key not null check (number>0),
name char(30),
country char(30))
tblWorks_for(
diver_number int
club_number int
end_working_date date)
tblCountry(
name char(30) not null primary key)
I need to write a query to return a name of a country and the number of "Super club" in it.
a Super club is a club which have more than 25 working divers (tblWorks_for.end_working_date is null) or had more than 100 diving's in it(tblDiving) in the last year.
after I get the country and number of super club, I need to show only the country's that contains more than 2 super club.
I wrote this 2 queries:
select tblDivingClub.name,count(distinct tblWorks_for.diver_number) as number_of_guids
from tblWorks_for
inner join tblDivingClub on tblDivingClub.number = tblWorks_for.club_number,tblDiving
where tblWorks_for.end_working_date is null
group by tblDivingClub.name
select tblDivingClub.name, count(distinct tblDiving.diving_number) as number_of_divings
from tblDivingClub
inner join tblDiving on tblDivingClub.number = tblDiving.diving_club
WHERE tblDiving.date_of_diving <= DATEADD(year,-1, GETDATE())
group by tblDivingClub.name
But I don't know how do I continue.
Every query works separately, but how do I combine them and select from them?
It's university assignment and I'm not allowed to use views or temporary tables.
It's my first program so I'm not really sure what I'm doing:)
WITH CTE AS (
select tblDivingClub.name,count(distinct tblWorks_for.diver_number) as diving_number
from tblWorks_for
inner join tblDivingClub on tblDivingClub.number = tblWorks_for.club_number,tblDiving
where tblWorks_for.end_working_date is null
group by tblDivingClub.name
UNION ALL
select tblDivingClub.name, count(distinct tblDiving.diving_number) as diving_number
from tblDivingClub
inner join tblDiving on tblDivingClub.number = tblDiving.diving_club
WHERE tblDiving.date_of_diving <= DATEADD(year,-1, GETDATE())
group by tblDivingClub.name
)
SELECT * FROM CTE
You can combine the queries using a UNION ALL as long as there are the same number of columns in each query. You can then roll them into a Common Table Expression (CTE) and do a select from that.
Can somebody help me out with a MS-SQL query please.
I have the following:
select Name from Keyword.dbo.NGrams
where Name not in (select Name from Keyword.dbo.Brands)
What I really want is something like this, but I can't get the syntax right
select Name from Keyword.dbo.NGrams
where Name not like (select Name from Keyword.dbo.Brands)
"not in" works great for NGrams & Brands that match exactly. But my NGrams are multiple words long and some contain a Brand within them.
Thanks so much
Edit: Maybe I can re-clarify what I am looking for my this pseudo sql:
select Name from Keyword.dbo.NGrams
where Description not containing (select Word from Keyword.dbo.Brands)
Brand is a list of single words. Description in NGrams would be a 2 or 3 word phrase. I want to select all the NGrams that do not contain any of the Brands
SELECT
n.Name
FROM Keyword.dbo.NGrams n
LEFT JOIN Keyword.dbo.Brands b
ON n.Name LIKE '%'+b.Name+'%'
WHERE b.Name IS NULL
SQL Fiddle Demo
If you want to avoid the Scunthorpe Problem and only match whole words, change the join condition to:
ON ' '+n.Name+' ' LIKE '% '+b.Name+' %'
Use a where not exists to express the like:
select Name
from Keyword.dbo.NGrams ng
where not exists (
select *
from Keyword.dbo.Brands b
where ng.Name like '%' + b.name + '%'
)
I ran a test using the ENABLE2K standard English word list. I generated 10 million random ngrams and 50000 random brands. The query takes about 1 minute to run on my workstation.
CREATE TABLE #enable2k (word varchar(max) NOT NULL)
BULK INSERT #enable2k FROM 'C:\enable2k.txt'
CREATE TABLE #ngrams (ngram_id int NOT NULL, word_num int NOT NULL, word varchar(max) NOT NULL, PRIMARY KEY(ngram_id, word_num));
INSERT #ngrams SELECT TOP 10000000 ROW_NUMBER() OVER(ORDER BY NEWID()), 1, word FROM #enable2k,(SELECT TOP 58 0 FROM master..spt_values) t(i)
INSERT #ngrams SELECT TOP 10000000 ROW_NUMBER() OVER(ORDER BY NEWID()), 2, word FROM #enable2k,(SELECT TOP 58 0 FROM master..spt_values) t(i)
INSERT #ngrams SELECT TOP 10000000 ROW_NUMBER() OVER(ORDER BY NEWID()), 3, word FROM #enable2k,(SELECT TOP 58 0 FROM master..spt_values) t(i)
CREATE TABLE #brands (brand varchar(32) NOT NULL PRIMARY KEY)
INSERT #brands SELECT TOP 50000 word FROM #enable2k WHERE LEN(word) <= 32 ORDER BY NEWID()
SELECT *
FROM #ngrams n
PIVOT (MIN(word) FOR word_num IN ([1],[2],[3])) n1
WHERE NOT EXISTS (
SELECT 1
FROM #ngrams n2
INNER JOIN #brands b
ON (n2.word = b.brand)
WHERE n1.ngram_id = n2.ngram_id
)
I'm trying to extract some data from a third party system which uses an SQL Server database. The DB structure looks something like this:
Order
OrderID OrderNumber
1 OX101
2 OX102
OrderItem
OrderItemID OrderID OptionCodes
1 1 12,14,15
2 1 14
3 2 15
Option
OptionID Description
12 Batteries
14 Gift wrap
15 Case
[etc.]
What I want is one row per order item that includes a concatenated field with each option description. So something like this:
OrderItemID OrderNumber Options
1 OX101 Batteries\nGift Wrap\nCase
2 OX101 Gift Wrap
3 OX102 Case
Of course this is complicated by the fact that the options are a comma separated string field instead of a proper lookup table. So I need to split this up by comma in order to join in the options table, and then concat the result back into one field.
At first I tried creating a function which splits out the option data by comma and returns this as a table. Although I was able to join the result of this function with the options table, I wasn't able to pass the OptionCodes column to the function in the join, as it only seemed to work with declared variables or hard-coded values.
Can someone point me in the right direction?
I would use a splitting function (here's an example) to get individual values and keep them in a CTE. Then you can join the CTE to your table called "Option".
SELECT * INTO #Order
FROM (
SELECT 1 OrderID, 'OX101' OrderNumber UNION SELECT 2, 'OX102'
) X;
SELECT * INTO #OrderItem
FROM (
SELECT 1 OrderItemID, 1 OrderID, '12,14,15' OptionCodes
UNION
SELECT 2, 1, '14'
UNION
SELECT 3, 2, '15'
) X;
SELECT * INTO #Option
FROM (
SELECT 12 OptionID, 'Batteries' Description
UNION
SELECT 14, 'Gift Wrap'
UNION
SELECT 15, 'Case'
) X;
WITH N AS (
SELECT I.OrderID, I.OrderItemID, X.items OptionCode
FROM #OrderItem I CROSS APPLY dbo.Split(OptionCodes, ',') X
)
SELECT Q.OrderItemID, Q.OrderNumber,
CONVERT(NVarChar(1000), (
SELECT T.Description + ','
FROM N INNER JOIN #Option T ON N.OptionCode = T.OptionID
WHERE N.OrderItemID = Q.OrderItemID
FOR XML PATH(''))
) Options
FROM (
SELECT N.OrderItemID, O.OrderNumber
FROM #Order O INNER JOIN N ON O.OrderID = N.OrderID
GROUP BY N.OrderItemID, O.OrderNumber) Q
DROP TABLE #Order;
DROP TABLE #OrderItem;
DROP TABLE #Option;