Need help in access query - sql

I have doubt in access query...
Pls advise is it possible
i have linked the excel file into access,its has some number of columns ..My ques is
for E.g
To retrieve the description and Region column from laptop,Desktop table
i do use below query
SELECT Laptop.[Description], Laptop.[Region] From Laptop
union SELECT Desktop.[Description], Desktop.[Region] From Desktop
sometimes ..It may not contain Region field, in that time I do use “ ” as Laptop.[Region] or "" as Desktop.[Region]
My quest is
Is there any option like this
SELECT Laptop.[Description], If Laptop.[Region]=avairable
then Laptop.[Region] else “” as [Region] from Laptop;
or any way to skip from error...
Please help me in this ...THx in advance
Doubt:
To be clear
If desktop table has description and region Column ..
Description Region
Saran east
Sathish north
sathy west
And
Laptop has Desktop table has description and Cost …
Description Cost
asdf 23
dkasfjasd 34
flkasdf 55
Select Laptop.[Description], NZ(Laptop.[Region], "NA") as [Region]
from Laptop
UNION
SELECT Desktop.[Description], NZ(Desktop.[Region], "NA") as [Region]
FROM Desktop;
Will it return this result ?
I can’t run this because I had some access issue
Description Region
asdf
dkasfjasd
flkasdf
Saran east
Sathish north
sathy west

I'm assuming you ment in your pseudo-code that '=avairable' means a value exists. You just want to handle a null value.
Select Laptop.Description, NZ(Laptop.Region, "") as [Region] from Laptop;
The NZ() function will handle the null values and substitute whatever you want.

you can use switch case for this query but in mS-acess its not supported but the other way out of doing it in access is use of iif() here I am giving you a generic example you can easily convert this in your actual query.
IIf(expr, truepart, falsepart)
SELECT IIF(IsNull(Laptop.[Region])," ",Laptop.[Region]) as region
FROM Laptop ;

Related

Finding a value and giving out some infos

coming back with a new question concerning SQL (Server 2016 or above).
I have a data view with 5 fields like:
ID_Card | ID_Name| ID_Details | ID_Date |ID_Validation
12345 Joe C30,C40,C50,C60 20.11.20 YES
Now I want to give out some information for ID_Details. If C30 is in the ID_Details, I want to give out some text like "Further information needed", for C40 for example I want to give out "No updates present". and so on. The Details list is limited to 5 entrys, which must not be present. The list is separated in the ID_Details field with an comma.
Thanks in advance!
Below is an example using a CASE expression with a STRING_SPLIT subquery. A better solution would be database design in (at least) first normal form.
SELECT
ID_Card
,ID_Name
,ID_Details
,ID_Date
,ID_Validation
, CASE WHEN EXISTS(
SELECT 1
WHERE 'C40' IN(
SELECT value
FROM STRING_SPLIT(ID_DETAILS,',')))
THEN 'Further information needed' END AS SomeText
FROM dbo.Example;

How to load grouped data with SSIS

I have a tricky flat file data source. The data is grouped, like this:
Country City
U.S. New York
Washington
Baltimore
Canada Toronto
Vancouver
But I want it to be this format when it's loaded in to the database:
Country City
U.S. New York
U.S. Washington
U.S. Baltimore
Canada Toronto
Canada Vancouver
Anyone has met such a problem before? Got a idea to deal with it?
The only idea I got now is to use the cursor, but the it is just too slow.
Thank you!
The answer by cha will work, but here is another in case you need to do it in SSIS without temporary/staging tables:
You can run your dataflow through a Script Transformation that uses a DataFlow-level variable. As each row comes in the script checks the value of the Country column.
If it has a non-blank value, then populate the variable with that value, and pass it along in the dataflow.
If Country has a blank value, then overwrite it with the value of the variable, which will be last non-blank Country value you got.
EDIT: I looked up your error message and learned something new about Script Components (the Data Flow tool, as opposed to Script Tasks, the Control Flow tool):
The collection of ReadWriteVariables is only available in the
PostExecute method to maximize performance and minimize the risk of
locking conflicts. Therefore you cannot directly increment the value
of a package variable as you process each row of data. Increment the
value of a local variable instead, and set the value of the package
variable to the value of the local variable in the PostExecute method
after all data has been processed. You can also use the
VariableDispenser property to work around this limitation, as
described later in this topic. However, writing directly to a package
variable as each row is processed will negatively impact performance
and increase the risk of locking conflicts.
That comes from this MSDN article, which also has more information about the Variable Dispenser work-around, if you want to go that route, but apparently I mislead you above when I said you can set the value of the package variable in the script. You have to use a variable that is local to the script, and then change it in the Post-Execute event handler. I can't tell from the article whether that means that you will not be able to read the variable in the script, and if that's the case, then the Variable Dispenser would be the only option. Or I suppose you could create another variable that the script will have read-only access to, and set its value to an expression so that it always has the value of the read-write variable. That might work.
Yes, it is possible. First you need to load the data to a table with an IDENTITY column:
-- drop table #t
CREATE TABLE #t (id INTEGER IDENTITY PRIMARY KEY,
Country VARCHAR(20),
City VARCHAR(20))
INSERT INTO #t(Country, City)
SELECT a.Country, a.City
FROM OPENROWSET( BULK 'c:\import.txt',
FORMATFILE = 'c:\format.fmt',
FIRSTROW = 2) AS a;
select * from #t
The result will be:
id Country City
----------- -------------------- --------------------
1 U.S. New York
2 Washington
3 Baltimore
4 Canada Toronto
5 Vancouver
And now with a bit of recursive CTE magic you can populate the missing details:
;WITH a as(
SELECT Country
,City
,ID
FROM #t WHERE ID = 1
UNION ALL
SELECT COALESCE(NULLIF(LTrim(#t.Country), ''),a.Country)
,#t.City
,#t.ID
FROM a INNER JOIN #t ON a.ID+1 = #t.ID
)
SELECT * FROM a
OPTION (MAXRECURSION 0)
Result:
Country City ID
-------------------- -------------------- -----------
U.S. New York 1
U.S. Washington 2
U.S. Baltimore 3
Canada Toronto 4
Canada Vancouver 5
Update:
As Tab Alleman suggested below the same result can be achieved without the recursive query:
SELECT ID
, COALESCE(NULLIF(LTrim(a.Country), ''), (SELECT TOP 1 Country FROM #t t WHERE t.ID < a.ID AND LTrim(t.Country) <> '' ORDER BY t.ID DESC))
, City
FROM #t a
BTW, the format file for your input data is this (if you want to try the scripts save the input data as c:\import.txt and the format file below as c:\format.fmt):
9.0
2
1 SQLCHAR 0 11 "" 1 Country SQL_Latin1_General_CP1_CI_AS
2 SQLCHAR 0 100 "\r\n" 2 City SQL_Latin1_General_CP1_CI_AS

Oracle: LIKE where any part of one string matches any part of another string

I am using PL/SQL v7.1
I am trying to find all address records where the country name has been entered in one of the address line fields, and also the country field.
The problem is that the country details have not been entered consistently eg.
addr4 addr5 country
---------- ---------- ---------------
JERSEY UK(JERSEY)
IRELAND REPUBLIC OFIRELAND
DOUGLAS ISLE OF MAN UK(ISLE OF MAN)  
So, I need to find the records where ANY PART of the Country field is also found in either addr4 or addr5.
I started with this
SELECT *
FROM test_addresses
WHERE addr4||addr5 LIKE '%'||country||'%'
I know this doesn't work because it will, taking the 1st record as an example, check if 'UK(JERESEY)' is found in addr4||addr5 and ,so, no match will be found. But how do I make it check if 'JERSEY' is found in addr4||addr5
Try this way:
SELECT *
FROM test_addresses
WHERE (addr4 is not null and country like '%'||addr4||'%')
or (addr5 is not null and country like '%'||addr5||'%')
Sql Fiddle Demo
I don't know so much about plsql
but I think your query is backwards, try this.
SELECT *
FROM test_addresses
WHERE country LIKE '%'||addr4||'%'
or country LIKE '%'||addr5||'%'

Microsoft Access Query - Convert Text to Numeric Depending on Field Contents - Low, Medium, High to 1,2 ,3

I am looking for a way to change the output of an access query to return either 1, 2 or 3 in replace of Low, Medium or High. I would like to convert the format of the field from Text to Numeric, since I wish to perform calculations using these numbers. Any ideas would be appreciated.
You can use iif() in MS Access:
select iif(col = 'High', 3, iif(col = 'Low', 1, 2)) as ColNumeric
Another possibility is switch, for example:
SELECT Field1,
Switch([field1]="Low",1,[Field1]="Medium",2,[Field1]="High",3) AS SwitchValue
FROM aTable
But it may be more convenient to simply create a small table with the substitute values and Join.
The best solution is to create a table with a number field (PK) and the text description. Something like
tblID | priorityKey
---------+----------------
1 | Low
2 | Medium
3 | High
Then when you need it, you simply JOIN them. Mind this needs to be updated in your table. You can simply run an Update Query.
However if you really need it get going now, I would suggest you use an IIF.

SQL: Select distinct based on regular expression

Basically, I'm dealing with a horribly set up table that I'd love to rebuild, but am not sure I can at this point.
So, the table is of addresses, and it has a ton of similar entries for the same address. But there are sometimes slight variations in the address (i.e., a room # is tacked on IN THE SAME COLUMN, ugh).
Like this:
id | place_name | place_street
1 | Place Name One | 1001 Mercury Blvd
2 | Place Name Two | 2388 Jupiter Street
3 | Place Name One | 1001 Mercury Blvd, Suite A
4 | Place Name, One | 1001 Mercury Boulevard
5 | Place Nam Two | 2388 Jupiter Street, Rm 101
What I would like to do is in SQL (this is mssql), if possible, is do a query that is like:
SELECT DISTINCT place_name, place_street where [the first 4 letters of the place_name are the same] && [the first 4 characters of the place_street are the same].
to, I guess at this point, get:
Plac | 1001
Plac | 2388
Basically, then I can figure out what are the main addresses I have to break out into another table to normalize this, because the rest are just slight derivations.
I hope that makes sense.
I've done some research and I see people using regular expressions in SQL, but a lot of them seem to be using C scripts or something. Do I have to write regex functions and save them into the SQL Server before executing any regular expressions?
Any direction on whether I can just write them in SQL or if I have another step to go through would be great.
Or on how to approach this problem.
Thanks in advance!
Use the SQL function LEFT:
SELECT DISTINCT LEFT(place_name, 4)
I don't think you need regular expressions to get the results you describe. You just want to trim the columns and group by the results, which will effectively give you distinct values.
SELECT left(place_name, 4), left(place_street, 4), count(*)
FROM AddressTable
GROUP BY left(place_name, 4), left(place_street, 4)
The count(*) column isn't necessary, but it gives you some idea of which values might have the most (possibly) duplicate address rows in common.
I would recommend you look into Fuzzy Search Operations in SQL Server. You can match the results much better than what you are trying to do. Just google sql server fuzzy search.
Assuming at least SQL Server 2005 for the CTE:
;with cteCommonAddresses as (
select left(place_name, 4) as LeftName, left(place_street,4) as LeftStreet
from Address
group by left(place_name, 4), left(place_street,4)
having count(*) > 1
)
select a.id, a.place_name, a.place_street
from cteCommonAddresses c
inner join Address a
on c.LeftName = left(a.place_name,4)
and c.LeftStreet = left(a.place_street,4)
order by a.place_name, a.place_street, a.id