How to convert access query to sql server query string? - sql-server

how to converse access query to sql server query string by programing?
example for access query string
SELECT dbo_VNMST.VISITDATE, dbo_VNTREAT.TREATMENTCODE, dbo_VNMST.HN, dbo_VNMST.VN, dbo_VNTREAT_1.TREATMENTCODE, Count(dbo_VNMST.HN) AS CountOfHN, dbo_PATIENT_NAME.SUFFIX, Mid([firstname],2) AS FIRSTNAME1, Mid([lastname],2) AS LASTNAME1, (FIRSTNAME1+' '+LASTNAME1) AS FULLNAME
FROM (((dbo_VNMST INNER JOIN dbo_VNTREAT ON (dbo_VNMST.VISITDATE = dbo_VNTREAT.VISITDATE) AND (dbo_VNMST.VN = dbo_VNTREAT.VN)) INNER JOIN dbo_VNPRES ON (dbo_VNMST.VISITDATE = dbo_VNPRES.VISITDATE) AND (dbo_VNMST.VN = dbo_VNPRES.VN)) INNER JOIN dbo_VNTREAT AS dbo_VNTREAT_1 ON (dbo_VNMST.VISITDATE = dbo_VNTREAT_1.VISITDATE) AND (dbo_VNMST.VN = dbo_VNTREAT_1.VN)) INNER JOIN dbo_PATIENT_NAME ON dbo_VNMST.HN = dbo_PATIENT_NAME.HN
GROUP BY dbo_VNMST.VISITDATE, dbo_VNTREAT.TREATMENTCODE, dbo_VNMST.HN, dbo_VNMST.VN, dbo_VNTREAT_1.TREATMENTCODE, dbo_PATIENT_NAME.SUFFIX, Mid([firstname],2), Mid([lastname],2)
HAVING (((dbo_VNMST.VISITDATE) Between #9/1/1466# And #9/14/1466#) AND ((dbo_VNTREAT.TREATMENTCODE)="3964") AND ((dbo_VNTREAT_1.TREATMENTCODE)="92H") AND ((dbo_PATIENT_NAME.SUFFIX)=0));

In addition to what Kane posted, you'll also need to replace the underscore ("_") between dbo and the table name with a period ("."), e.g.:
SELECT dbo_VNMST.VISITDATE
will become
SELECT dbo.VNMST.VISITDATE

You'll need to use the SUBSTRING function instead of the MID function, replace double quotes with a single quote and remove the hash (#) identifier for your BETWEEN statement.

Related

Executing part of stored procedure based on condition

I am trying to load to a table based on load types - Full or Incremental that is being passed as parameter in stored procedure. I was able to try with substitution variable with one line of code previously, but the below code doesn't seem to work -
Stored procedure possible arguments:
LOAD_TYPE=FULL
LOAD_TYPE=INCR
var incr_condition = (load_type=='INCR')?"INNER JOIN temp_table"
with temp_table(
select data
from table a
where dt between 01-01-2019 and 09-09-2020
)
select *
from table b
${incr_condition} -- execute only if load_type=INCR
INNER JOIN TABLE C ON B.ID = C.ID
Is there any way to restrict the with clause to execute only if the load_type==INCR? Please advice.
I think the conditional operator (question mark) must have a false part in addition to the true part. Otherwise, it generates a syntax error when there's a semicolon ending the line. This example obviously doesn't run anything, but it will return the values assigned to the "out" variable, which would be run.
Since you're using a replacement variable ${incr_condition} be sure to use backticks to open and close your SQL string.
create or replace procedure foo(LOAD_TYP string)
returns string
language javascript
as
$$
var load_type = LOAD_TYP;
var incr_condition = (load_type === 'INCR') ? "INNER JOIN temp_table" : "";
var out = `
with temp_table(
select data
from table a
where dt between 01-01-2019 and 09-09-2020
)
select *
from table b
${incr_condition} -- execute only if load_type=INCR
INNER JOIN TABLE C ON B.ID = C.ID
`;
return out;
$$;
call foo('INCR'); --Adds the inner join
call foo('FULL'); --Does not add the inner join
I also recommend changing your comparison on strings from == to ===. For details on why, reference What is the correct way to check for string equality in JavaScript?.

Updating one table's column in SQL Server from another

I have a table of measurements from weather stations, with station names (in Hebrew):
I also have created a table of those weather stations with their latitudes and longitudes:
I've written a query that should update the first table with the lat/longs from the second, but it's not working:
update t1
set t1.MeasurementLat = t2.Latitude,
t1.MeasurementLong = t2.Longitude
from [dbo].[Measurements] as t1
inner join [dbo].[StationCoords] as t2 on t1.StationName like t2.Station
I think there is a problem with the way the station name is being read, and perhaps something to do with encoding, because this query brings back an empty result, too:
SELECT TOP (5) *
FROM [dbo].[Measurements]
WHERE [StationName] = 'אריאל מכללה';
Any ideas?
Your example names are not the same. Perhaps this will work:
update m
set MeasurementLat = sc.Latitude,
MeasurementLong = sc.Longitude
from dbo.[Measurements] m join
dbo.[StationCoords] sc
on m.StationName like sc.Station + '%';

To add a condition dynamically in PowerBuilder

I'm new to Power Builder code. I need to add a condition to Join dynamically. Any help is appreciated. Thanks a lot
String szdSQL, psql, sznewsql
szdSQL = "Select A, B, C, D
FROM sy_staging
LEFT OUTER JOIN fd_M
ON sy_staging.id = fd_M.id
LEFT OUTER JOIN gl_M
ON sy_staging.id= gl_M.id AND sy_staging.version = gl_M.version
WHERE sy_staging.year = :lyear AND
sy_staging.location = :llocation "
psql = "Upper(fd_M.code3) = 'SMM' "
In my new query I want to add the condition present in this string variable (psql) in the join as below
sznewsql = " "Select A, B, C, D
FROM sy_staging
LEFT OUTER JOIN fd_M
ON sy_staging.id = fd_M.id AND Upper(fd_M.code3) = 'SMM'
LEFT OUTER JOIN gl_M
ON sy_staging.id= gl_M.id AND sy_staging.version = gl_M.version
WHERE sy_staging.year = :lyear AND
sy_staging.location = :llocation "
Hmmm... That's an interesting case - adding a parameter to the ON clause, not the WHERE clause.
I'd use a datawindow, for sure (because I always do), but I'm not sure you can do that in graphic mode. You might have to convert to syntax, and then just add the new parameter into the ON clause with the ":" syntax.
LEFT OUTER JOIN fd_M
ON sy_staging.id = fd_M.id AND Upper(fd_M.code3) = :newStringParm
LEFT OUTER JOIN gl_M
...
and then your PowerScript would be
dw_1.retrieve( lYear, lLocation, psql )
-Paul Horan-
If you're only going to have those two different SQLs, you could just create two separate datawindows and then dynamically swap out the one used in the datawindow control.

T-SQL Left Join using "or" operator

I have the following query where I would like to pull in either or both on a match. There can be more than one ID or HIC for a member. So if the member ID = member ID then pull the max (loaddate) for the most current HIC Likewise if HIC = HIC pull in the member ID with the max (loaddate). I want to include the left join in case a match isn't found for either scenario.
Code:
SELECT
CH1.*
,AVM.MBR_ID
,AVM.HIC
,AVM.MBR_LST_NM
,AVM.MBR_FST_NM
,CAST(AVM.MBR_BIRTH_DT AS DATE) AS 'MBR_BIRTH_DT'
,AVM.LOADDATE
FROM
#CHECK1 CH1
LEFT JOIN
AVRIL.DBO.VW_MBR AVM ON (CH1.HICN = AVM.HIC OR CH1.MEMBER_ID = AVM.MBR_ID)
WHERE
CH1.HEALTH_PLAN = 'AVRIL'
AND AVM.LOADDATE=(SELECT MAX(LOADDATE) FROM AVRIL.DBO.VW_MBR)
Thanks,
Michael
When you use a field from the VW_MBR table in the where clause, it effectively turns the left join into an inner join. Put the condition in the join:
...
FROM #CHECK1 CH1
LEFT JOIN AVRIL.DBO.VW_MBR AVM ON (CH1.HICN = AVM.HIC OR CH1.MEMBER_ID = AVM.MBR_ID)
AND AVM.LOADDATE=(SELECT MAX(LOADDATE) FROM AVRIL.DBO.VW_MBR)
WHERE CH1.HEALTH_PLAN = 'AVRIL'
Here may be an alternative to the first proposed answer, I'm using a custom query as jointure in order to optimize it (I use only the max load dates instead of trying the jointure on every rows of the table).
SELECT CH1.*
,MAVM.MBR_ID
,MAVM.HIC
,MAVM.MAX_LOADDATE
FROM #CHECK1 CH1
LEFT JOIN (SELECT AVM.HIC
,AVM.MBR_ID
MAX(AVM.LOADDATE) AS [MAX_LOADDATE]
FROM AVRIL.DBO.VW_MBR AVM
GROUP BY AVM.HIC, AVM.MBR_ID) MAVM (MAVM.HIC = CH1.HICN
OR MAVM.MBR_ID = CH1.MEMBER_ID)
WHERE CH1.HEALTH_PLAN = 'AVRIL'
I simplified the query to focus on the changes in comparison with the other proposed query. You can still add an INNER JOIN clause to AVRIL.DBO.VM_MBR in order to get additional columns:
...
LEFT JOIN (...) MAVM ...
INNER JOIN AVRIL.DBO.VW_MBR AVM2 ON AVM2.HIC = MAVM.HIC
AND AVM2.MBR_ID = MAVM.MBR_ID
AND AVM2.LOADDATE = MAVM.MAX_LOADDATE
...
So you can use AVM2.xxx for the columns you want to use.
Hope this will help

Translating a QueryExpression into SQL: what's a Natural join?

I am trying to translate a QueryExpression that is in some existing code into a T-SQL select statement.
I've run across the following statement and I'm having trouble understanding what they mean by a Natural Join:
linkEntity1.JoinOperator = JoinOperator.Natural;
Would this be equivalent to an Inner Join in T-SQL? Googling has not been much help.
Here's the rest of the QueryExpression Code:
QueryExpression query = new QueryExpression();
query.EntityName = "showinfo";
ColumnSet columns = new ColumnSet();
columns.Attributes = new String[] { "company" };
query.ColumnSet = columns;
query.Criteria = new FilterExpression();
query.Criteria.FilterOperator = LogicalOperator.And;
ConditionExpression condition1 = new ConditionExpression();
condition1.AttributeName = "company";
condition1.Operator = ConditionOperator.NotNull;
query.Criteria.Conditions = new ConditionExpression[] { condition1 };
LinkEntity linkEntity1 = new LinkEntity();
linkEntity1.JoinOperator = JoinOperator.Natural;
linkEntity1.LinkFromEntityName = "show";
linkEntity1.LinkFromAttributeName = "showid";
linkEntity1.LinkToEntityName = "showintegration";
linkEntity1.LinkToAttributeName = "showcode";
linkEntity1.LinkCriteria = new FilterExpression();
linkEntity1.LinkCriteria.FilterOperator = LogicalOperator.And;
ConditionExpression condition2 = new ConditionExpression();
condition2.AttributeName = "showend";
condition2.Operator = ConditionOperator.Null;
linkEntity1.LinkCriteria.Conditions = new ConditionExpression[] { condition2 };
query.LinkEntities = new LinkEntity[] { linkEntity1 };
There is no equivalent in SQL Server of a natural join where table intersect is based on column names by the RDBMS.
I'm glad of that because it is at best ambiguous and at worst dangerous. JOINs should be explicit. Examples why:
having a InsertedBy column in both tables (quite common): should we have to prefix with the table name to remove ambiguity?
future DDL that add columns that change JOIN semantics
See
Natural join in SQL Server
SQL Server - lack of NATURAL JOIN / x JOIN y USING(field)
Edit:
It looks like natural join means "don't repeat the column in the output" (like USING in MySQL would do) according to the JoinOperator Enumeration.
If I understand this (debatable!) it's misleading. Especially when I read the "LeftOuter" narrative..
A natural join compares all columns in the two tables that have the same column names. It's equivalent to an inner join with the matching columns explicitly listed.
Yes - the natural join is inner join - so you can write:
select * from tab1, tab2 where tab1.col1 = tab2.col1
as
select * from tab1 inner join tab2 on tab1.col1 = tab2.col1

Resources