I have converted a sql query written by an other senoir developer who also is the group lead and I am new to programming. He wrote a query that was reading a collection of rows from DB by sending array of parameters, For example:
SELECT [LastName],[FirstMidName],[EnrollmentDate]
FROM [ContosoUniversity1].[dbo].[Student]
WHERE ([LastName] ='Alexander' AND [FirstMidName] = 'Carson')
OR ([LastName] ='Justice' AND [FirstMidName] = 'Peggy')
However, I was given an assignment to improve the security of the query. I did some changes to apply sqlParameter() to the query. The query was written as:
SELECT [LastName],[FirstMidName],[EnrollmentDate]
FROM [ContosoUniversity1].[dbo].[Student]
WHERE [LastName] IN ('Alexander','Justice')
AND [FirstMidName] IN ('Carson','Peggy')
So basically its follows the where.. in clause that I can further do my other tasks. And these two lines give the same result but he insisted that mine was logically bad. I have very hard time to understand his explanation and self-doubt that if I am doing wrong to convert this query. Could anyone share any opinion?
The first query will only bring in an exact grouping of names. Imagine if someone else went to the school called Carson Justice. Your query would bring him in, the seniors query would not.
I.e.
FirstMidName | LastName
Alexander | Carson
Peggy | Justice
Peggy | Carson
Alexander | Justice
Seniors query would return Alexander Carson, Peggy Justice
Your query would return all 4 names (Alexander Carson, Peggy Justice, Peggy Carson, Alexander Justice)
Yours is logically wrong because it will bring in Peggy Alexander. The first query won't bring her in. And that doesn't seem like the intent of the exercise.
Related
Not sure if this is possible but I'm hoping it is. I am using MS Access for Estate Planning for work. I've gotten to the point where I've got the data to look like this:
File_Name
Executor_1
Executor_2
Beneficiary_1
Beneficiary_2
Hill, Hank
Peggy Hill
Peggy Hill
Hill, Hank
Bobby Hill
Bobby Hill
Gribble, Dale
Nancy Gribble
Gribble, Dale
Joseph Gribble
Joseph Gribble
Gribble, Dale
John Redcorn
But I need it to look like this:
File_Name
Executor_1
Executor_2
Beneficiary_1
Beneficiary_2
Hill, Hank
Peggy Hill
Bobby Hill
Peggy Hill
Bobby Hill
Gribble, Dale
Nancy Gribble
Joseph Gribble
Joseph Gribble
John Redcorn
I need it in the latter format so I can use MailMerge in word and create the Will. Can anyone provide any guidance? We don't currently use any software for Est. Planning so anything beats having to go into Word manually and retype everything. Please let me know if more information is needed.
Edit:
This is what the SQL looks like:
TRANSFORM Last(File_Roles.File_Name) AS LastOfFile_Name
SELECT File_Roles.Executor_1,
File_Roles.Executor_2,
File_Roles.Beneficiary_1,
File_Roles.Beneficiary_2,
File_Roles.Trustee_1,
File_Roles.Trustee_2,
File_Roles.Guardian_1,
File_Roles.Guardian_2,
File_Roles.ATTY_IF_1, File_Roles.ATTY_IF_2,
File_Roles.HCATTY_IF_1,
File_Roles.HCATTY_IF_2
FROM File_Roles
GROUP BY File_Roles.Executor_1,
File_Roles.Executor_2,
File_Roles.Beneficiary_1,
File_Roles.Beneficiary_2,
File_Roles.Trustee_1,
File_Roles.Trustee_2,
File_Roles.Guardian_1,
File_Roles.Guardian_2,
File_Roles.ATTY_IF_1,
File_Roles.ATTY_IF_2,
File_Roles.HCATTY_IF_1,
File_Roles.HCATTY_IF_2
PIVOT File_Roles.File_Name;
You can use GROUP BY and MAX()
SELECT
t.File_Name,
MAX(t.Executor_1) As Executor_1,
MAX(t,Executor_2) As Executor_2,
MAX(t.Beneficiary_1) As Beneficiary_1,
MAX(t.Beneficiary_2) As Beneficiary_2
FROM table_or_query t
GROUP BY File_Name
But maybe you can fix your original crosstab query to do this right away. Probably you are doing the grouping wrong. You must group by File_Name in the crosstab query and apply Max to the total row of the value (so it is difficult to say without seeing this query).
GROUP BY File_Name means that one row is created for each distinct value of File_Name.
Since this will merge several rows into one, you must specify an aggregate function for every column in the SELECT list not listed in the GROUP BY clause. This can be e.g. SUM(), AVG(), MIN() or MAX(). See SQL Aggregate Functions for a complete list. Since any Null value is considered to be less than any other value, MAX() will take this non-Null value from the merged rows.
I have a quick question regarding writing a SQL query to obtain a complete entry from two or more entries where the data is missing in different columns.
This is the example, suppose I have this table:
Client Id | Name | Email
1234 | John | (null)
1244 | (null) | john#example.com
Would it be possible to write a query that would return the following?
Client Id | Name | Email
1234 | John | john#example.com
I am finding this particularly hard because these are 2 entires in the same table.
I apologize if this is trivial, I am still studying SQL and learning, but I wasn't able to come up with a solution for this and I although I've tried looking online I couldn't phrase the question in the proper way, I suppose and I couldn't really find the answer I was after.
Many thanks in advance for the help!
Yes, but actually no.
It is possible to write a query that works with your example data.
But just under the assumption that the first part of the mail is always equal to the name.
SELECT clients.id,clients.name,bclients.email FROM clients
JOIN clients bclients ON upper(clients.name) = upper(substring(bclients.email from 0 for position('#' in bclients.email)));
db<>fiddle
Explanation:
We join the table onto itself, to get the information into one row.
For this we first search for the position of the '#' in the email, get the substring from the start (0) of the string for the amount of characters until we hit the # (result of positon).
To avoid case-problems the name and substring are cast to uppercase for comparsion.
(lowercase would work the same)
The design is flawed
How can a client have multiple ids and different kind of information about the same user at the same time?
I think you want to split the table between clients and users, so that a user can have multiple clients.
I recommend that you read information about database normalization as this provides you with necessary knowledge for successfull database design.
I need to get exact name string match from multiple values using Contains function.
I used below query to get data which matches exactly JOHN SMITH OR MIKE DAVID but query is fetching all data which has JOHN SMITH, JOHN, SMITH, MIKE, DAVID, MIKE DAVID, JOHN..SMITH, JOHN/SMITH,....
where contains(names,'{JOHN SMITH} OR {MIKE DAVID}')>0
Note - I don't want to use multiple like in OR conditions.We need to pass around 200 to 300 values (names) to do match pattern.
Can anyone let me know how to get exact match from multiple values using CONTAINS?
Thanks
Anand
I don't use Oracle but i liked this question and i will try to answer it based on what i read on Oracle's documentation, regarding CONTAINS.
so i am currently reading about Stored Query Expression (SQE),
Stored Query Expression (SQE)
Use the SQE operator to call a stored query expression created with
the CTX_QUERY.STORE_SQE procedure.
Stored query expressions can be used for creating predefined bins for
organizing and categorizing documents or to perform iterative queries,
in which an initial query is refined using one or more additional
queries.
So perhaps you could pass all the names you want to query in such a way. For example:
begin
ctx_query.store_sqe('mynames', 'JOHN SMITH OR MIKE DAVID OR GEORGE HARRIS OR JOHN DOE');
end;
And then call it:
SELECT SCORE(1), nameid FROM mytable
WHERE CONTAINS(names, 'sqe(mynames)', 1)> 0
ORDER BY SCORE(1);
Hope this was helpful.
Due to the way a particular table is written I need to do something a little strange in SQL and I can't find a 'simple' way to do this
Table
Name Place Amount
Chris Scotland
Chris £1
Amy England
Amy £5
Output
Chris Scotland £1
Amy England £5
What I am trying to do is above, so the null rows are essentially ignored and 'grouped' up based on the Name
I have this working using For XML however it is incredibly slow, is there a smarter way to do this?
This is where MAX would work
select
Name
,Place = Max(Place)
,Amount = Max(Amount)
from
YourTable
group by
Name
Naturally, if you have more than one occurance of a place for a given name, you may get unexpected results.
I have a tricky problem that I wouldn't mind a bit of help on, I've made some progress using queries that I've here and elsewhere, but am getting seriously stumped now.
I have a mailing list that has numerous near duplications that I'm trying to combine into one meaningful row, taking data such as this.
Title Forename Surname Address1 Postcode Phone Age Income Ownership Gas
Mrs D Andrews 122 Somewhere BH10 123456 66-70 Homeowner
Ms Diane Andrews 122 Somewhere BH10 123456 £25-40 EDF
and making one row along the lines of
Title Forename Surname Address1 Postcode Phone Age Income Ownership Gas
Mrs Diane Andrews 122 Somewhere BH10 123456 66-70 £25-40 Homeowner EDF
I have over 127 million records, most duplicated with a similar pattern, but no clear logic as was proven when I added an identity field. I also have over 90 columns to consider, so it's a bit of work!
There isn't a clear pattern to the data, so I'm thinking I may have a huge case statement to try to climb over.
Using the following code I can get a decent start on only returning the full name, but with the pattern of data - trying to compare the fields across rows is as follows.
SELECT c1.*
FROM
Mailing c1
JOIN
Mailingc2 ON c1.Telephone1 = c2.Telephone1 AND c1.surname = c2.surname
WHERE
len(c1.Forename) > len(c2.Forename)
AND c2.over_18 <> ''
AND c1.Telephone1 = '123456'
Has anyone got any pointers as to how I should progress please? I'm open to discussion and ideas...
I'm using SQL 2005 and apologies in advance if the tagging is all over the place!
Cheers,
Jon
Would it work by assuming that all persons with the same surname and phone number (Do all persons have a phone?) were the same person?
INSERT INTO newtable <fieldnames>
SELECT lastname,phone,max(field3),max(field4)....
FROM oldtable
GROUP BY lastname,phone
But that would collapse John Smith and Jack Smith living together into one person.
Perhaps you should consider outsourcing it to a data-entry sweatshop somewhere, adter you have preprocessed the data. :-)
And/or be prepared to take the flack for mistaken bundling.
Perhaps adding something like "To improve our green footprint, we have merged x listings on your adress together. If you would like separate mailings, please contact us"