Adding multiple strings in WHERE clause - SQL - sql

For the record I am a newbie when it comes to SQL. I am practicing and getting familiar with the syntax, and how it is all structured. I am using this website as a crash course in SQL. If you follow the link and take a look at question #5 the directions state to pull up data related only to three countries that of France, Germany, and Italy.
My dilemma is that I do not understand how multiple strings should be structured.
Here is my code:
SELECT name, population
FROM world
WHERE name = 'france';
The code above will produce a table with both selected columns, and the row that contains France's data, but I still need two other rows with data. However, when I try to edit it to achieve the results I need it won't work:
SELECT name, population
FROM world
WHERE name = 'germany' 'france' 'italy';
The code above only produces columns and the rows disappear. I need my table to include the name and population of all three countries. I have searched for a simple answer on how to properly add multiple strings and haven't found anything conclusive.
Despite my issue being relatively simple, I still seek help from all y'all, so please help!
Thank you!

Try to use IN operator, that allows you to make multiple values in WHERE clause.
Your code should look like this:
SELECT name, population
FROM world
WHERE name IN ('france','Germany','Italy');

You can put many criteria in a WHERE clause. Use AND and OR to combine them (and parentheses when needed such as in where a = 1 and (b = 2 or c = 3)). So your query can be written as
SELECT name, population
FROM world
WHERE name = 'germany' OR name = 'france' OR name = 'italy';
As has been shown, however, when looking for several values of one attribute you can replace all the ORs with an IN clause:
WHERE name IN ('germany', 'france', 'italy')
which is more readable and hence preferable.

Related

Convert Xpath to SQL

Previously we were fetching a number of countries from a table. Now the table changed to support multiple languages inside the text cell. The previous SQL statement was:
select b.text, a.iso_num, a.iso2, a.iso3, a.kfz, a.ind_member
from schema.zl_countrycode a, schema.zl_countrycode_lsd b
where a.ind_land = 1 and a.kfz is not NULL and dat_end = to_date('99991231','YYYYMMDD') and a.ZL_COUNTRYCODE_id = b.ZL_COUNTRYCODE_LSD_ID order by text
The list previously outputted each country in a row.
With the addition of the language selection, the list suddenly doubled in size - because it lists every county in two different languages.
This is how the table looks with the GUI
I'm trying to figure out, how to expend the statement to only select each "DE:" value in the text column. After having a quick indirect discussion with the developers, they provided me this XPATH statement:
Parentofparent/Parent/Valuestable[name="ZL_COUNTRYCODE"]/Valueclassification[name="TEXT"]/Value/ValueLng[lng="DE"]
I don't know the first thing about XPATH and no matter what I have tried so far, it failed.
Please help me out if you're knowledgeable in this field. It's probably an Oracle database, as I have experienced a plethora of Oracle error codes in the last few days.
I think this should do the trick:
SELECT b.TEXT
,a.iso_num
,a.iso2
,a.iso3
,a.kfz
,a.ind_member
,a.de
FROM SCHEMA.zl_countrycode a
JOIN SCHEMA.zl_countrycode_lsd b
ON a.ZL_COUNTRYCODE_id = b.ZL_COUNTRYCODE_LSD_ID AND b.spec_lng = 'DE'
WHERE a.ind_land = 1
AND a.kfz IS NOT NULL
AND dat_end = to_date('99991231', 'YYYYMMDD')
ORDER BY TEXT

SQL - How to "flatten" several very similar rows into 1

Apologies if the title isn't clear - I just didn't know how to describe the issue and I really don't know SQL that well/at all.
I am working with a database used by our case management system. At places it has clearly been extended over time by the developers. I am working with Contact details (names, addresses, etc...) and they have added extra fields to deal with email addresses and to allow for home/work/mobile phone numbers etc...
The problem is that they haven't added a new field for each individual new field. They have instead added a couple of fields in 2 different tables - the first field includes the field name, the second then includes the actual data.
The first is called AddElTypeText in a table called AdditionalAddElTypes - The AddElTypeText field includes values like "Work Telephone 1", "Fax", "Home Email" etc... (There are a total of 10 different values and I can't see the developers expanding this number any time soon)
The second field is called AddElementText in a table called AdditionalAddressElements - the AddElementText then includes the actual data e.g. the phone number, email address.
For those of you who (unlike me) find it easier to look at the SQL code, it's:
SELECT
Address.AddressLine1
,AdditionalAddElTypes.AddElTypeText
,AdditionalAddressElements.AddElementText
FROM
Address
INNER JOIN AdditionalAddressElements
ON Address.AddressID = AdditionalAddressElements.AddressID
INNER JOIN AdditionalAddElTypes
ON AdditionalAddressElements.AddElTypeID = AdditionalAddElTypes.AddElTypeID
I can work with this, but if any contact has 2 or more "additional" elements, I get multiple rows, with most of the data being the same, but just the 2 columns of AddElTypeText and AddElementText being different.
So can anyone suggest anything to "flatten" a contact into a single row. I had in mind something like concatenating AddElTypeText and AddElementText into a single string field, ideally with a space in between AddElTypeText and AddElementText, and then a : or , separating the pairs of AddElTypeText and AddElementText.
However, I have very little idea how to achieve that, or whether an entirely different approach would be better. Any help very gratefully received!
Gary
As #twn08 said, this type of question has generally been asked before. It's generally a pain to do this kind of grouping concatenation in SQL Server, involving the use of FOR XML.
That being said, here's a SQLFiddle that (I believe) does something like what you wanted. And here's the actual query:
WITH Results AS
(
SELECT a.*,
t.AddElTypeText,
aa.AddElementText
FROM
Address a
INNER JOIN
AdditionalAddressElements aa
ON a.AddressID = aa.AddressID
INNER JOIN
AdditionalAddElTypes t
ON aa.AddElTypeID = t.AddElTypeID
)
SELECT
res.AddressID,
STUFF((
SELECT ', ' + AddElTypeText + ': ' + AddElementText
FROM Results
WHERE (AddressID = res.AddressID)
FOR XML PATH (''))
,1,2,'') AS AdditionalElements
FROM Results res
GROUP BY res.AddressID

SQL Server 2008: Finding strings within a table which contain the word World

I'm trying to filter my query to show only table entries with the word WORLD and also contains other country codes.
I have used the wildcard function but I am unsure as to how I can have it only return entries with both WORLD and other country codes.
SELECT *
FROM [****].[dbo].[Titles]
WHERE Territories LIKE '%world%'
Any help is appreciated
EDIT: Expected result would return all rows with both WORLD and one or more country code in the field. The territories column in this table contains both World or country codes and should bot contain both. the reason im running this query is to search for any rows with bad data.
You could try something like this
SELECT *
FROM [****].[dbo].[Titles]
WHERE Territories LIKE '%world%'
AND Territories LIKE '%countryCode%'
but I am not sure how fast that will be. If you know that the other country codes will always come after the world code, you could do something like this
SELECT *
FROM [****].[dbo].[Titles]
WHERE Territories LIKE '%world%countryCode%'
which I think should run faster.
Well if it can contain other country codes and world then you need
WHERE Territories LIKE '%world%' AND Territories LIKE '%{other country code}%'
If you are looking at world or other country code you need
WHERE Territories LIKE '%world%' OR Territories LIKE '%{other country code}%'

SQL - multiple conditions in DCount() function

I am using MS Access 2007.
A: DCount("[Name]","[Main]","[Name] = 'Mark'")/
DCount("[Entry]","[Main]","[Entry] = 1")
Okay, so I am basically counting the number of people with the name Mark and I am dividing it by the number of Entry's that = 1 in my database. That's easy enough, but I am trying to apply a third condition, where
[Location]![City] = 'Chicago'
, but Access isn't letting me do this (It can't find the table, even though it's in the table I specified above.
DCount("[Name]","[Main]","[Name] = 'Mark' AND [Location]![City] = 'Chicago'")/
DCount("[Entry]","[Main]","[Entry] = 1")
I have also tried filtering the city with a Where clause in the Design view, but the condition is being applied after the calculation above, so the calculation is the same regardless of the city. I just need it to perform the above calculation for the city of Chicago.
Is something like this possible with DCount?
Also, I would die a happy man if you could tell me how to Group By the city While performing the calculations for each one separately, but I would also be very thankful if someone could just show me how to do it the first way too.
Thanks
What is [Location]![City]? My answer is based on the presumption it refers to a field named City in a table named Location.
If that is correct, I think your problem is because you're attempting to specify a condition based on a field which is not part of the domain ([Main]) you told DCount to use.
From Microsoft's Documentation, the domain is "A string expression identifying the set of records that constitutes the domain. It can be a table name or a query name for a query that does not require a parameter."
So if you want your DCount criteria to refer to fields in two tables, consolidate the tables in the form of a query into a single "domain". Maybe your query could be something like this, "qryMainWithCity":
SELECT m.[Name], m.Entry, m.City_ID, l.City
FROM
Main AS m
INNER JOIN Location AS l
ON m.City_ID = l.City_ID;
If that query works for your situation, you should be able to get what you want with a DCount expression like this:
DCount("*","qryMainWithCity","[Name] = 'Mark' AND City = 'Chicago'")
I was just posting the same answer as #HansUp's came up. I have an alternative way to do it, and that's to use an instant recordset lookup:
Dim varReturnValue as Variant
varReturnValue = CurrentDB.OpenRecordset("SELECT Main.[Name] FROM Main INNER JOIN Location ON Main.City_ID = Location.City_ID WHERE Main.[Name] = 'Mark' AND Location.City = 'Chicago';")(0)
That returns the first field in the recordset returned (the index is zero-based). That way you don't have to save a query.

SQL Group By

If I have a set of records
name amount Code
Dave 2 1234
Dave 3 1234
Daves 4 1234
I want this to group based on Code & Name, but the last Row has a typo in the name, so this wont group.
What would be the best way to group these as:
Dave/Daves 9 1234
As a general rule if the data is wrong you should fix the data.
However if you want to do the report anyway you could come up with another criteria to group on, for example LEFT(Name, 4) would perform a grouping on the first 4 characters of the name.
You may also want to consider the CASE statement as a method (CASE WHEN name = 'Daves' THEN 'Dave' ELSE name), but I really don't like this method, especially if you are proposing to use this for anything else then a one-off report.
If it's a workaround, try
SELECT cname, SUM(amount)
FROM (
SELECT CASE WHEN NAME = 'Daves' THEN 'Dave' ELSE name END AS cname, amount
FROM mytable
)
GROUP BY cname
This if course will handle only this exact case.
For MySQL:
select
group_concat(distinct name separator '/'),
sum(amount),
code
from
T
group by
code
For MSSQL 2005+ group_concat() can be implemented as .NET custom aggregate.
Fix the typo? Otherwise grouping on the name is going to create a new group.
Fixing your data should be your highest priority instead of trying to devise ways to "work around" it.
It should also be noted that if you have this single typo in your data, it is likely that you have (or will have at some point in the future) even more screwy data that will not cleanly fit into your code, which will force you to invent more and more "work arounds" to deal with it, when you should be focusing on the cleanliness of your data.
If the name field is suppose to be a key then the assumption has to be that Dave and Daves are two different items all together, and thus should be grouped differently. If however it is a typo, then as other have suggested, fix the data.
Grouping on a freeform entered text field if that is what this is, will always have issues. Data entry is never 100%.
To me it makes more sense to group on the code alone if that is the key field and leave name out of the grouping all together.