USING rather than ON - sql-server

I'm looking at a section of "A Guide to the SQL Standard" (C.J.Date/Hugh Darwen) concerning LEFT JOIN and it gives the following syntax:
table-reference [ NATURAL ] outer-join-type
JOIN table-reference
[ ON conditional-expression
| USING ( column-commalist ) ]
What is USING?
Is it useful?
Is it implemented in SQL-Server?

No, it's not supported by SQL Server, see FROM:
<joined_table> ::=
{
<table_source> <join_type> <table_source> ON <search_condition>
| <table_source> CROSS JOIN <table_source>
| left_table_source { CROSS | OUTER } APPLY right_table_source
| [ ( ] <joined_table> [ ) ]
}
As to what it is? It's a way of performing a join between two tables where the column names in both tables exactly match, and as a convenience, it allows you to name the columns only once. Compare that to using ON to achieve the same:
ON
table1.columnA = table2.columnA AND
table1.columnB = table2.columnB AND
table1.columnC = table2.columnC
with USING it's just:
USING (columnA,columnB,columnC)

No, the USING clause for joins isn't supported in SQL Server (or Sybase). You'll need to continue to use ON clauses.
There's a request on MSDN connect to have it implemented here - but as it was suggested in 2006 and not implemented yet, I wouldn't hold your breath!

Related

Sum Partition by order by in SQL Server [duplicate]

I get an execution error in following SQL script:
SELECT TOP 1 PERCENT
a.accode, a.voucherdate, a.credit, a.Debit,
SUM(a.Debit) OVER (ORDER BY [a.accode],[a.voucherdate]) AS rdr
FROM
VoucherMain AS a
ORDER BY
a.accode, a.voucherdate
Error message
Incorrect syntax near 'order'
Can anyone tell me what's wrong with my syntax?
The problem is that you need SQL Server 2012 and above. Okay, I added the "and above" for future visitors, but compare 2008 OVER CLAUSE with 2012 OVER CLAUSE.
The 2008 version has this important note:
When used in the context of a ranking window function, <ORDER BY
Clause> can only refer to columns made available by the FROM clause.
An integer cannot be specified to represent the position of the name
or alias of a column in the select list. <ORDER BY Clause> cannot be
used with aggregate window functions.
In SQL Server 2008, you can only use the OVER clause to partition aggregate functions, not apply an order:
Ranking Window Functions
< OVER_CLAUSE > :: =
OVER ( [ PARTITION BY value_expression , ... [ n ] ]
< ORDER BY_Clause> )
Aggregate Window Functions
< OVER_CLAUSE > :: =
OVER ( [ PARTITION BY value_expression , ... [ n ] ] )
Note that there's no <ORDER BY Clause> for the aggregates.

What is LEVEL equivalent in snowflake

I have to convert one oracle query to snowflake,which has a where clause LEVEL > 1. Could you please suggest me the best option.
Thanks.
I don't think it's an exact match, but the closest thing is the "start with" clause of Snowflake's connect by:
SELECT <column_list> [ , <level_expression> ]
FROM <data_source>
START WITH <predicate>
CONNECT BY [ PRIOR ] <col1_identifier> = [ PRIOR ] <col2_identifier>
[ , [ PRIOR ] <col3_identifier> = [ PRIOR ] <col4_identifier> ]
...
...
You can provide a where clause on the start with predicate, but without the "where" keyword. You can read more about it here: https://docs.snowflake.com/en/sql-reference/constructs/connect-by.html
There is level in snowflake. The differences from Oracle are:
In snowflake it's neccesary to use prior with connect by expression.
And you can't just select level - there should be any existing column in the select statement.
Example:
SELECT LEVEL, dummy FROM
(select 'X' dummy ) DUAL
CONNECT BY prior LEVEL <= 3;
LEVEL DUMMY
1 X
2 X
3 X
4 X

How to find misspellings in data

I am trying to find the misspellings in TOWN_C field. Data looks something like below. There is no specific pattern, sometimes misspelling can be at the beginning, sometimes it can be in middle or at the end. Length of misspelling can be different too.
I am using SQL Server Management Studio to execute the queries. I used SUBSTR to find out duplicates along with the left outer join. But that does not give only misspelling. I still need to go and manually look at data.
Data ->
Achampet
ACHEMPET
AGIA
AGIYA
ASHOK NAGAR
ASHOKNAGAR
ASHOKNAGER
SQL query which I am using ->
Select distinct(T3.TOWN__C)
From (Select T1.Sub_Str, Count(T1.Sub_Str) as Y
From (SELECT TOWN__C, SUBSTRING(TOWN__C, 1, 3) as Sub_Str
FROM [SALESFORCE].[dbo].[Outlet Master] group by TOWN__C)T1
Group by T1.Sub_Str having count(*)> 1)T2
Left outer join
[SALESFORCE].[dbo].[Outlet Master]T3
On T2.Sub_Str = SUBSTRING(T3.TOWN__C, 1, 3)
Order by T3.TOWN__C
Is there a way to find out all such cases using SQL or Excel or anything else?
Here's an example using SOUNDEX, to try to locate values where multiple spellings have been used for "similar" names:
declare #t table (town varchar(35) not null)
insert into #t(town) values
('Achampet'),
('ACHEMPET'),
('AGIA'),
('AGIYA'),
('ASHOK NAGAR'),
('ASHOKNAGAR'),
('ASHOKNAGER'),
('Downtown'),
('DOWNTOWN'),
('DownTown')
select
v.*
from
(select
*,
MIN(town) OVER (PARTITION BY town_sound) as minTown,
MAX(town) OVER (PARTITION BY town_sound) as maxTown
from
#t
cross apply
(select SOUNDEX(REPLACE(town,' ','')) as town_sound) u
) v
where minTown != maxTown
Note that this doesn't return "downtown" where the only variations are in capitalization, but does return all of the values in your given sample data, which I assume were all meant to be found as possible misspellings.
Also note that SOUNDEX has had a chequered history and under older versions of SQL Server it was usually recommended that a "better" soundex be implemented as a UDF. You should be able to find versions of that with a simple search, if required.
Note, also, that Soundex was specifically designed around English pronunciation. Again, you may be able to find a better tailored function as a UDF for specific other languages.
Results:
town town_sound minTown maxTown
------------- ---------- ------------- ------------
AGIA A200 AGIA AGIYA
AGIYA A200 AGIA AGIYA
ASHOK NAGAR A225 ASHOK NAGAR ASHOKNAGER
ASHOKNAGAR A225 ASHOK NAGAR ASHOKNAGER
ASHOKNAGER A225 ASHOK NAGAR ASHOKNAGER
Achampet A251 Achampet ACHEMPET
ACHEMPET A251 Achampet ACHEMPET

CodeIgniter ActiveRecord join statement dropping '[' from the ON clause

Using Codeigniter (v1.7.2) Active Record Class to query a MSSQL Database (external DB, I don't control table or field names)
The following Code:
$this->db->select('[Key Field], MemberInfo.OtherField');
$this->db->limit(10);
$this->db->from('primaryTable');
$this->db->join('MemberInfo', '[Member Number] = Member_Number', 'left');
$this->db->where('[Member Number] = 573');
$this->db->where('[Incident Date] BETWEEN '. $DateStart . ' AND ' . $DateEnd);
Produces the following Query (which has a syntax error)
SELECT TOP 10 [Key Field], MemberInfo.OtherField
FROM primaryTable
LEFT JOIN MemberInfo ON Member Number] = Member_Number
WHERE [Member Number] = '573'
AND [Incident Date] BETWEEN 2012-01-01 AND 2012-07-19
Note the JOIN clause, which is missing the opening '[' on the field name
I tried using double quotes, which yielded the same result.
Anyone have ideas, is this a known bug in 1.7.2 (which I know is old, working up updating)?
UPDATE
issue is present in 2.1.2 also
Accepted answer below is also the fix for 2.1.2: change the regex check in the JOIN function to look for the opening [
The problem is in the parameter ON. There does not exist an integrated solution in the framework (not in version 2).
You have 2 options:
Altering the core of the library active_record
Write the query in a complete chain with concatenations using $this->db->query();

Problem with generated SQL from Hibernate (MS SQLServer)

I have a problem with Hibernate generating an SQL that do not work on SQLServer (works on PostgreSQL without any problems). I have tried to set the hibernate dialect for SQLServer but the same SQL is still generated and still do not work. The HQL query looks like this:
select count(t) from ValidationLog t
The generated SQL looks like this:
select count((vl.dataKey, vl.dataType)) from ValidationLog vl;
So my question is if there is anyway around it? Would really like to have the same code for both databases.
According to the JPA specification, your JPQL query is perfectly valid:
4.8 SELECT Clause
...
The SELECT clause has the following
syntax:
select_clause ::= SELECT [DISTINCT] select_expression {, select_expression}*
select_expression ::=
single_valued_path_expression |
aggregate_expression |
identification_variable |
OBJECT(identification_variable) |
constructor_expression
constructor_expression ::=
NEW constructor_name ( constructor_item {, constructor_item}*)
constructor_item ::= single_valued_path_expression | aggregate_expression
aggregate_expression ::=
{ AVG | MAX | MIN | SUM } ([DISTINCT] state_field_path_expression) |
COUNT ([DISTINCT] identification_variable | state_field_path_expression |
single_valued_association_path_expression)
However, you might be a victim of a bug reported in issues like HHH-4044, HHH-3096, HHH-2266 (or even HHH-5419).
Possible workaround: use a state_field_path_expression.
select count(t.someField) from ValidationLog t
The HQL looks wrong to me, should be:
select count(t.dataKey) from ValidationLog t

Resources