SQL Server 2008 - insert into column from 2 different tables - sql-server

I am wondering how I would have a single column, for example called ClientID, I want to be able to select from two different tables and have all the results go into this column.
This is what I am currently trying but I am getting errors:
SELECT ClientID = ('basic' + CAST(a.BasicCID as VARCHAR(15))) AND =('premium' + CAST(c.PremiumCID as VARCHAR(15)))
I want the output to display something like this
ClientID Name
------- --------
basic1 John
basic2 Pat
premium1 Mary
premium2 Sean

Okay, You can do something like this -
Insert into YourTable(ClientID, Name)
SELECT 'basic' + CAST(a.BasicCID as VARCHAR(15)), Name From BasicTable a
UNION
SELECT 'premium' + CAST(c.PremiumCID as VARCHAR(15)), Name From PremiumTable c

Related

Select query using NOT IN in SQL Server 2008

I have two tables Sales and Return:
Sales table:
DocNum ItemCode
101 itemcode1
101 itemcode2
102 itemcode3
102 itemcode2
Return table:
DocNum ItemCode
101 itemcode1
102-reject itemcode2
Desired output:
DocNum ItemCode
101 itemcode2
102 itemcode3
I need to select data from the Sales table that does not exist in the Return table, using a NOT IN condition. I only get records that match DocNum column on the two tables, my problem here is user put a word 'reject' on the Return table.
Is there a way to to match the docnum column in these situation?
You can achieve what you want using a LEFT JOIN:
SELECT s.DocNum
FROM Sales s LEFT JOIN Return r
ON s.DocNum = CASE WHEN CHARINDEX('-', r.DocNum) > 0
THEN SUBSTRING(r.DocNum, 1, CHARINDEX('-', r.DocNum)-1)
ELSE r.DocNum
END AND
s.ItemCode = r.ItemCode
WHERE r.DocNum IS NULL
By the way, you should rethink your database design and stop putting the word "reject" into an id column, which makes querying the table difficult. Instead, add a new boolean column called reject to keep track of this.
SELECT *
FROM Sales s
WHERE NOT EXISTS
(
SELECT *
FROM [Return] r
WHERE r.DocNum LIKE s.DocNum + '%'
)
As far as the question is concerned, the query below should return the expected output, even if the DocNum is set to something like "102/reject" or "102(reject)" or whatever.
select a.DocNum, a.ItemCode
from SalesTable a
left join ReturnTable b on charindex(a.DocNum, b.DocNum) > 0
and a.ItemCode = b.ItemCode
where b.DocNum is null
However, as far as sensible table design is concerned, allowing DocNum to be updated to 102-reject is a bad practice. This exposes a few design flaws:
DocNum is a varchar column instead of a more suitable integer column
Allowing user to manipulate what is obviously a key column may introduce SQL injection risks.
and what happens when DocNum is updated to "102-101"?

Assistance With query across 2 tables within specified date range

I have 2 tables in a large SQL Database and i need to query across them and I am struggling TBH. Here are the parameters:
Table 1 - Live Policies
Table 2 - Email Addresses
Common Pivot = Client number which is present in both tables.
From Table 1 i need to retrieve the following fields:
Client Number
Ref Number
Name
Postcode
Inception date
Policy Type (= 'PC')
Select Client, Ptype, Ref, Incep, [Name], Postcode from [Live
Policies] where Ptype = 'PC'
This works fine.
From Table 2 i need to retrieve:
Webaddr
My question is how do i return the email address for the required records from the second table by referencing the client number? (client number is the same for all records) The second part of the statement is where i'm getting stuck.. I'm aware of the JOIN statement but if i try this i just get nowhere.. Help most appreciated!
USE a JOIN
select L.Client, L.Ptype, L.Ref, L.Incep, L.[Name], L.Postcode, E.Webaddr
from [Live Policies] as L
JOIN [Email Addresses] as E
ON L.Client = E.Client
where Ptype = 'PC'

How to collate rows to a delimited string in SQL2008R2

We are currently upgrading a current data import process we have written in C#.
As part of the upgrade process, we need to check the results of the import process from the rewrite against the results of the old system.
One of the changes we made was breaking comma-delimited lists into rows in another table. This will enable us to filter results using a simple join.
This is the old schema:
FormNumber MainCategories
1 blue,green,red
2 yellow,red,blue
3 white
Which we normalized to:
FormNumber AttributeId Value
1 1 blue
1 1 green
1 1 red
2 1 yellow
2 1 red
2 1 blue
3 1 white
Now, our next step is to confirm that the results from the two processes are the same. One of these checks is to compare the MainCategories field of the old process with the results from the normalized tables.
This leads us, finally, to the question: How do I create a comma-delimited list of the new schema to compare to the value of the old.
We have tried the XMLPath solution proposed by #Ritesh here: Concatenate many rows into a single text string?
Here is the adapted sql statement:
Select distinct ST2.FormNumber,
(Select ST1.Value + ',' AS [text()]
From cache.ArtifactAttribute ST1
Where ST1.FormNumber= ST2.FormNumber
ORDER BY ST1.FormNumber
For XML PATH ('')) [Values]
From cache.ArtifactAttribute ST2
The problem is the results are not correct. Even though FormNumber 1 only has three entries in the table, the Values column (the dynamically built delimited string) shows incorrect results. Obviously we are not implementing the sql code correctly.
What are we doing wrong?
Here is a way for you to try:
SELECT DISTINCT A.FormNumber, MainCategories
FROM YourTable A
CROSS APPLY (SELECT STUFF((SELECT ',' + Value
FROM YourTable
WHERE FormNumber = A.FormNumber FOR XML PATH('')),1,1,'') MainCategories) B
Though there is the problem where you can't really be sure that the order of the items concatenated is the same as the one you have, since there isn't a column that explictly gives that order. Here is a working SQL Fiddle with this example.
This seems to work fine for me:
DECLARE #s TABLE(FormNumber int, AttributeId int, Value varchar(32));
INSERT #s VALUES
(1,1,'blue'),
(1,1,'green'),
(1,1,'red'),
(2,1,'yellow'),
(2,1,'red'),
(2,1,'blue'),
(3,1,'white');
SELECT ST2.FormNumber, [Values] = STUFF(
(SELECT ',' + ST1.Value AS [text()]
FROM #s ST1
WHERE ST1.FormNumber = ST2.FormNumber
ORDER BY ST1.FormNumber
FOR XML PATH (''),
TYPE).value(N'./text()[1]', N'varchar(max)'), 1, 1, '')
FROM #s ST2 GROUP BY ST2.FormNumber;
Results:
FormNumber
Values
1
blue,green,red
2
yellow,red,blue
3
white
Example db<>fiddle

How to return multiple results in a subquery?

I have a visitor table that looks like this:
VID Name Address DOB
001 Bob 101 St 03/05/2001
002 James 505 Rd 02/06/1985
003 Jill 201 Place 04/06/1970
And a visits table that looks like this:
VID Date Reason
001 05/07/2012 Family
001 06/01/2012 Family
003 03/02/2011 Other
I want to do a join query between these two on VID (which I already did) but also have the query show all (multiple) results from visits. So the results would look like:
Name DOB Visits
Bob 03/05/2001 05/07/2012 Family, 06/01/2012 Family
James 02/06/1985
Jill 04/06/1970 03/02/2011 Other
Is this possible? I attempted a subquery like:
SELECT Name, DOB, (SELECT Date, Reason FROM visits AS H WHERE H.VID=visitor.VID) As Visits FROM visitor;
But that gave me the obvious Subquery returned more than 1 value error. The data would be parsed by PHP, but I was hoping to accomplish this in one query.
You can use a FOR XML PATH construct to concatenate your results into one column
SELECT Name
, DOB
, STUFF((SELECT ', '
+ CONVERT(VARCHAR(16), H.Date, 101)
+ ' '
+ H.Reason
FROM visits AS H
WHERE H.VID = visitor.VID
FOR XML PATH('')), 1, 2, '')
FROM visitor;
Note that various date formats are supported with convert. I have used 101 in the example wich translates to mm/dd/yyyy.
Have a look at MSDN for all styles supported by convert.
You'll have to join the two tables and then do the processing in php. So
SELECT a.Name, a.DOB, b.Date, b.Reason FROM visitor a, visits b where a.VID=b.VID order by 1,2 ;
Then you just have to walk through the records and start a new line whenever one of the first two columns changes.

LIKE function in SQL Server 2008 suggestion needed

I have a table Customer with 2 columns Name and Surname (sql Server 2008). User wants to search by Name-Surname - or just typing Jo Bloggs. Suppose a row is filled with
CustomerId Name Surname
1 Jo Bloggs
doing
select * from customer where Name like '%Jo%' will find the records
select * from customer where Surname like '%Bloggs%' will find the records
But How can I make it return records for if user types both Name and Surname eg Jo Bloggs?
You could also create a computed column and search on that:
ALTER TABLE dbo.customer
ADD FullName as Name + ' ' + Surname PERSISTED
Now you'd have an extra column FullName in your customer table, which is always up to date, and you can search for:
SELECT (list of fields) FROM dbo.customer
WHERE Fullname = 'Jo Bloggs'
and since it's a persisted, computed column, you can even put an index on it to make exact searches faster
This should work whether user enters First Name, Surname or both.
SELECT *
FROM customer cus
WHERE ((cus.Name like #FirstName) OR (#FirstName IS NULL)) AND
((cus.Surname like #Surname) OR (#Surname IS NULL))
I used two variables because entering input values into an SQL string is strongly discouraged, as it exposes to SQL Injection (other than being slower).
select * from customer where Name like '%Jo%' and Surname like '%Bloggs%'
select * from customer where Name like '%Jo%'
union
select * from customer where Surname like '%Bloggs%'

Resources