Getting a SQL Query to work in Access - sql

I have the following Query written in MS SQL Server:
select
(select (CAST( count(*) as decimal (38,4))) from Inventor) /
(select (CAST( count(*) as decimal(38,4))) from General);
which works perfectly, but when I try to use it in Access it doesn't work at all.
Help please!
Ok so it doesnt have to be cast as decimal, a float would work as well.
My Inventor table has the PK from the General table as a FK in it. The issue is that if something has multiple inventors listed on it. So i Tried the following:
SELECT TotalInventors/TotalPatents
(SELECT COUNT (DISTINCT PatentNo) FROM Inventor AS TotalPatents
(SELECT COUNT (*) FROM Inventor AS TotalInventors))
FROM Inventor;
Still with a syntax error

The syntax for Select in Access does NOT allow you to write a select without a "from".
Access Grammar:
SELECT [predicate] { * | table.* | [table.]field1 [AS alias1] [, [table.]field2 [AS alias2] [, ...]]}
FROM tableexpression [, ...] [IN externaldatabase] --FROM is NOT optional
[WHERE... ]
[GROUP BY... ]
[HAVING... ]
[ORDER BY... ]
[WITH OWNERACCESS OPTION]
SQL Server Grammar:
[ WITH <common_table_expression>]
SELECT select_list [ INTO new_table ]
[ FROM table_source ] [ WHERE search_condition ] --FROM is optional
[ GROUP BY group_by_expression ]
[ HAVING search_condition ]
[ ORDER BY order_expression [ ASC | DESC ] ]
As you can see here, the [ ] mean that something is optional. And the [ ] are wrapping the "From" the SQL Server Grammar, but not in the Access Grammar.
So, basically, your query is invalid in Access because it needs a "FROM"
Now this is a little bit inconsistent, while this :
select ( 1 ) / ( 1 )
Or this
select ( 1 )
will get me a valid answer, this will give me a syntax error in Access (but it does work in SQL Server):
select ( select 1 ) / ( select 1 )
You need a "dual" table, so that you can write:
select ( select 1 from Dual) / ( select 1 from Dual) from Dual.
Here is how you can create one

In the current version of your question, Access complains with this part of your query because Access SQL doesn't support COUNT (DISTINCT anything).
SELECT COUNT (DISTINCT PatentNo) FROM Inventor
You could rewrite that piece as:
SELECT Count(*) FROM
(SELECT DISTINCT PatentNo
FROM Inventor);
However adapting the full query to use that will be more challenging. Consider whether a single Access query to give you TotalInventors/TotalPatents is really the best way to go. I suspect you could make the SQL coding task easier for yourself by splitting that into 2 queries (one to give you TotalInventors and another to give you TotalPatents). Then do the division in your client code which calls the queries.

I think this will work:
SELECT
CDbl( ci ) / CDbl( cg ) AS result
FROM
(SELECT COUNT(*) AS ci FROM Inventor) AS i
,
(SELECT COUNT(*) AS cg FROM General) AS g ;
The comma , would be written as CROSS JOIN in other DBMS.

Related

weird where clasue in TSQL

In the code snippet below I see a column in a where clause that I have never seen or used before. The code works and is not my code. My question is if this is some kind of "customized" TSQL language or if is legitimate to have a column in a where clause and if so what is the scope of it.
For example this clause " WHERE FMTREFl :vall" why the :val1?
SELECT 1
,FMTTRANTYPE
,FMTSTATUS
,FMTTIMEDATE
,FMTREF2
,FMTREF3
,FMTSEQNO
FROM FMTRANS
WHERE FMTREFl :vall
OR FMTHDR ANY (
SELECT FMTHSEQNO
FROM FMTRANSHDR
WHERE FMTHICPNO :val2
)
UNION ALL
SELECT 0
,FMTTRANTYPE
,FMTSTATUS
,FMTTIMEDATE
,FMTREF2
,FMTREF3
,FMTSEQNO
FROM FMTRANSIN
WHERE FMTREFl :val3
OR FMTHDR ANY (
SELECT FMTHSEQNO
FROM FMTRANSHDR
WHERE FMTHICPNO :val4
)
ORDER BY FMTTIMEDATE ASC

Using WITH in MonetDB

I'm trying to execute the next query in MonetDB using "WITH":
with a as (select data_string from colombia.dim_tempo)
select
t.ano_mes
,f.sg_estado
,f.cod_produto
, sum(f.qtd_vendidas) as qtd_vendidas
, count(*) as fact_count
from colombia.fact_retail_market f, colombia.dim_tempo t
where f.cod_anomes = t.data_string
and t.data_string in (a.data_string)
group by
t.ano_mes
,f.sg_estado
,f.cod_produto ;
But always get this message:
What's wrong with the sentence?
The WHERE clause needs to be:
WHERE f.cod_anomes = t.data_string AND
t.data_string IN (SELECT data_string FROM a)
That is, IN needs to be followed by a subquery against the CTE.

Regex extract in BigQuery issue

I'm trying to simplify a column in BigQuery by using BigQuery extract on it but I am having a bit of an issue.
Here are two examples of the data I'm extracting from:
dc_pre=CLXk_aigyOMCFQb2dwod4dYCZw;gtm=2wg7f1;gcldc=;gclaw=;gac=UA-5815571-8:;auiddc=;u1=OVERDRFT;u2=undefined;u3=undefined;u4=undefined;u5=SSA;u6=undefined;u7=na;u8=undefined;u9=undefined;u10=undefined;u11=undefined;~oref=https://www.online.bank.co.za/onlineContent/ga_bridge.html
dc_pre=COztt4-tyOMCFcji7Qod440PCw;gtm=2wg7f1;gcldc=;gclaw=;gac=UA-5815571-8:;auiddc=;u1=DDA13;u2=undefined;u3=undefined;u4=undefined;u5=SSA;u6=undefined;u7=na;u8=undefined;u9=undefined;u10=undefined;u11=undefined;~oref=https://www.online.support.co.za/onlineContent/ga_bridge.html
I want to extract the portion between ;u1= and ;u2
Running the following legacy SQL Query
SELECT
Date(Event_Time),
Activity_ID,
REGEXP_EXTRACT(Other_Data, r'(?<=u1=)(.*\n?)(?=;u2)')
FROM
[sprt-data-transfer:dtftv2_sprt.p_activity_166401]
WHERE
Activity_ID in ('8179851')
AND Site_ID_DCM NOT IN ('2134603','2136502','2539719','2136304','2134604','2134602','2136701','2378406')
AND Event_Time BETWEEN 1563746400000000 AND 1563832799000000
I get the error...
Failed to parse regular expression "(?<=u1=)(.*\n?)(?=;u2)": invalid
perl operator: (?<
And this is where my talent runs out, is the error being caused because I'm using legacy SQL? Or is an unsupported format for REGEX?
Just tried this, and it worked, but with "Standart SQL" enabled.
select
other_data,
regexp_extract(other_data, ';u1=(.+?);u2') as some_part
from
unnest([
'dc_pre=CLXk_aigyOMCFQb2dwod4dYCZw;gtm=2wg7f1;gcldc=;gclaw=;gac=UA-5815571-8:;auiddc=;u1=OVERDRFT;u2=undefined;u3=undefined;u4=undefined;u5=SSA;u6=undefined;u7=na;u8=undefined;u9=undefined;u10=undefined;u11=undefined;~oref=https://www.online.bank.co.za/onlineContent/ga_bridge.html',
'dc_pre=COztt4-tyOMCFcji7Qod440PCw;gtm=2wg7f1;gcldc=;gclaw=;gac=UA-5815571-8:;auiddc=;u1=DDA13;u2=undefined;u3=undefined;u4=undefined;u5=SSA;u6=undefined;u7=na;u8=undefined;u9=undefined;u10=undefined;u11=undefined;~oref=https://www.online.support.co.za/onlineContent/ga_bridge.html'
]) as other_data
Not using regex but it still works...
with test as (
select 1 as id, 'dc_pre=CLXk_aigyOMCFQb2dwod4dYCZw;gtm=2wg7f1;gcldc=;gclaw=;gac=UA-5815571-8:;auiddc=;u1=OVERDRFT;u2=undefined;u3=undefined;u4=undefined;u5=SSA;u6=undefined;u7=na;u8=undefined;u9=undefined;u10=undefined;u11=undefined;~oref=https://www.online.bank.co.za/onlineContent/ga_bridge.html' as my_str UNION ALL
select 2 as id, 'dc_pre=COztt4-tyOMCFcji7Qod440PCw;gtm=2wg7f1;gcldc=;gclaw=;gac=UA-5815571-8:;auiddc=;u1=DDA13;u2=undefined;u3=undefined;u4=undefined;u5=SSA;u6=undefined;u7=na;u8=undefined;u9=undefined;u10=undefined;u11=undefined;~oref=https://www.online.support.co.za/onlineContent/ga_bridge.html'
),
temp as (
select
id,
split(my_str,';') as items
from test
),
flattened as (
select
id,
split(i,'=')[SAFE_OFFSET(0)] as left_side,
split(i,'=')[SAFE_OFFSET(1)] as right_side
from temp
left join unnest(items) i
)
select * from flattened
where left_side = 'u1'

BigQuery select expect double nested column

I am trying to remove a column from a BigQuery table and I've followed the instructions as stated here:
https://cloud.google.com/bigquery/docs/manually-changing-schemas#deleting_a_column_from_a_table_schema
This did not work directly as the column I'm trying to remove is nested twice in a struct. The following SO questions are relevant but none of them solve this exact case.
Single nested field:
BigQuery select * except nested column
Double nested field (solution has all fields in the schema enumerated, which is not useful for me as my schema is huge):
BigQuery: select * replace from multiple nested column
I've tried adapting the above solutions and I think I'm close but can't quite get it to work.
This one will remove the field, but returns only the nested field, not the whole table (for the examples I want to remove a.b.field_name. See the example schema at the end):
SELECT AS STRUCT * EXCEPT(a), a.* REPLACE (
(SELECT AS STRUCT a.b.* EXCEPT (field_name)) AS b
)
FROM `table`
This next attempt gives me an error: Scalar subquery produced more than one element:
WITH a_tmp AS (
SELECT AS STRUCT a.* REPLACE (
(SELECT AS STRUCT a.b.* EXCEPT (field_name)) AS b
)
FROM `table`
)
SELECT * REPLACE (
(SELECT AS STRUCT a.* FROM a_tmp) AS a
)
FROM `table`
Is there a generalised way to solve this? Or am I forced to use the enumerated solution in the 2nd link?
Example Schema:
[
{
"name": "a",
"type": "RECORD",
"fields": [
{
"name": "b",
"type": "RECORD"
"fields": [
{
"name": "field_name",
"type": "STRING"
},
{
"name": "other_field_name".
"type": "STRING"
}
]
},
]
}
]
I would like the final schema to be the same but without field_name.
Below is for BigQuery Standard SQL
#standardSQL
SELECT * REPLACE(
(SELECT AS STRUCT(SELECT AS STRUCT a.b.* EXCEPT (field_name)) b)
AS a)
FROM `project.dataset.table`
you can test, play with it using dummy data as below
#standardSQL
WITH `project.dataset.table` AS (
SELECT STRUCT<b STRUCT<field_name STRING, other_field_name STRING>>(STRUCT('1', '2')) a
)
SELECT * REPLACE(
(SELECT AS STRUCT(SELECT AS STRUCT a.b.* EXCEPT (field_name)) b)
AS a)
FROM `project.dataset.table`

What does 'AS' mean in SQL?

Below is the synopsis of SELECT from the PostgreSQL documentation. It seems to me that sometimes we write <expression> AS <name> and sometimes it's <name> AS <expression>. In ordinary English, I tend to think <expression> AS <name> is much more common (e.g. "Address her as. Doctor Smith, please., and I'm having trouble understanding how to think about <name> AS <expression>.
How can we distinguish between where to use <name> AS <expression> and <expression> as <name>?
What are minimal obvious examples of each?
Are there parallels of each kind in ordinary language, which would make it intuitively obvious when to use what?
[ WITH [ RECURSIVE ] with_query [, ...] ]
SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
* | expression [ [ AS ] output_name ] [, ...]
[ FROM from_item [, ...] ]
[ WHERE condition ]
[ GROUP BY expression [, ...] ]
[ HAVING condition [, ...] ]
[ WINDOW window_name AS ( window_definition ) [, ...] ]
[ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ]
[ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ]
[ LIMIT { count | ALL } ]
[ OFFSET start [ ROW | ROWS ] ]
[ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]
[ FOR { UPDATE | SHARE } [ OF table_name [, ...] ] [ NOWAIT ] [...] ]
where from_item can be one of:
[ ONLY ] table_name [ * ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
( select ) [ AS ] alias [ ( column_alias [, ...] ) ]
with_query_name [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
function_name ( [ argument [, ...] ] ) [ AS ] alias [ ( column_alias [, ...] | column_definition [, ...] ) ]
function_name ( [ argument [, ...] ] ) AS ( column_definition [, ...] )
from_item [ NATURAL ] join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ]
and with_query is:
with_query_name [ ( column_name [, ...] ) ] AS ( select | values | insert | update | delete )
TABLE [ ONLY ] table_name [ * ]
I like the question.
Here is how I see it and how I explain it to people, hope it helps:
Let's start with <expression> as <name>. The simplest analogy from real life is an abbreviation. It was created to make the code cleaner, easier to read and simply shorter. Let's imagine a scenario: we have data on all students from the Massachusetts Institute of Technology as well as Massachusetts Department of Motor Vehicles in our database and we want to find students that have speeding tickets and how much they have paid.
SELECT
government.SocialSecurityAdministration.FirstName,
government.SocialSecurityAdministration.LastName,
education.MasachusettsInstituteOfTechnology.Faculty
government.DepartmentOfMotorVehiclesTickets.TicketTotal,
government.SocialSecurityAdministration.SocialSecurityNumber
FROM
education.MasachusettsInstituteOfTechnology
INNER JOIN government.DepartmentOfMotorVehiclesTickets ON education.MasachusettsInstituteOfTechnology.SocialSecurityNumber = government.DepartmentOfMotorVehicles.SocialSecurityNumber
INNER JOIN government.SocialSecurityAdministration ON government.DepartmentOfMotorVehicles.SocialSecurityNumber = government.SocialSecurityAdministration.SocialSecurityNumber
Looks ugly, doesn't it? In real life, we've abbreviated the Massachusetts Institute of Technology to be MIT and the Department of Motor Vehicles to be DMV. I'm not aware of the official abbreviation for Social Security Administration (but we can come up with one) though we say SSN when we mean Social Security Number. Let's implement this idea:
SELECT
ssnAdm.FirstName,
ssnAdm.LastName,
ssnAdm.Faculty
dmv.TicketTotal,
ssnAdm.SocialSecurityNumber AS ssn
FROM
education.MasachusettsInstituteOfTechnology AS mit
INNER JOIN government.DepartmentOfMotorVehiclesTickets AS dmv ON mit.SocialSecurityNumber = dmv.SocialSecurityNumber
INNER JOIN government.SocialSecurityAdministration AS ssAdm ON dmv.SocialSecurityNumber = dmv.SocialSecurityNumber
Looks better now, doesn't it?
Now to the <name> as <expression> portion of it. This is done to simplify the code as well as some performance optimizations but let's focus on simplification for now. Using the same example I've used above, you might want to get/ask the following: "For every MIT student that has received a ticket I need to know the last 4 digits of their SSN, their last name, the amount of money in their bank account and their last VISA transaction amount". Yes, you work for CIA.
Let's write it:
SELECT
RIGHT(4,ts.ssn) as LastFourDigitsSsn,
ts.LastName,
bad.TotalAmount,
ISNULL(visa.TransactionAmt,'Student uses MasterCard') AS VisaTransaction
FROM
(SELECT
ssnAdm.FirstName,
ssnAdm.LastName,
ssnAdm.Faculty
dmv.TicketTotal,
ssnAdm.SocialSecurityNumber AS ssn
FROM
education.MasachusettsInstituteOfTechnology AS mit
INNER JOIN government.DepartmentOfMotorVehiclesTickets AS dmv ON mit.SocialSecurityNumber = dmv.SocialSecurityNumber
INNER JOIN government.SocialSecurityAdministration AS ssAdm ON dmv.SocialSecurityNumber = dmv.SocialSecurityNumber
) AS ts
INNER JOIN business.BankAccountsData AS bad ON ts.ssn = bad.SocialSecurityNumber
OUTER APPLY (SELECT TOP 1 TransactionAmt FROM business.VisaProcessingData vpd WHERE vpd.BankAccountID = bad.ID ORDER BY TransactionDateTime DESC) as visa
Well, looks ugly again. But what if we simplify it a bit and express certain things outside of the actual statement? That's when <name> as <expression> comes in. Let's do it:
WITH MitTicketedStudents AS (
SELECT
ssnAdm.LastName,
ssnAdm.SocialSecurityNumber as ssn,
RIGHT(4,ssnAdm.SocialSecurityNumber) as LastFourDigitsSsn
FROM
education.MasachusettsInstituteOfTechnology AS mit
INNER JOIN government.DepartmentOfMotorVehiclesTickets AS dmv ON mit.SocialSecurityNumber = dmv.SocialSecurityNumber
INNER JOIN government.SocialSecurityAdministration AS ssAdm ON dmv.SocialSecurityNumber = dmv.SocialSecurityNumber
),
LatestVisaTransactions AS (
SELECT DISTINCT
BankAccountID,
FIRST_VALUE(TransactionAmt) OVER (PARTITION BY BankAccountId ORDER BY TransactionDateTime DESC) as TransactionAmt
FROM
business.VisaProcessingData
)
-- And let's use our expressions now
SELECT
mts.LastFourDigitsSsn,
mts.LastName,
bad.TotalAmount,
ISNULL(lvt.TransactionAmt,'Student uses MasterCard') AS VisaTransaction
FROM
MitTicketedStudents mts
INNER JOIN business.BankAccountsData AS bad ON mts.ssn = bad.SocialSecurityNumber
LEFT OUTER JOIN LatestVisaTransactions lvt ON bad.ID = lvt.BankAccountID;
Looks better, doesn't it?
Conclusion: when you want to separate code you use <name> as <expression>, when you want to give something an alias to simplify code you use <expression> as <name>.
What matters is where it appears.
mytable:
mycolumn myothercolumn
----------------------
1 a
2 b
SELECT myrow.mycolumn * 2 AS mylabel
FROM (SELECT * FROM mytable) AS myrow
WHERE myrow.mycolumn > 1
mylabel
-------
4
In SELECT, we refer to the value of an expression AS some output column name ("column alias"). In FROM, we refer to (a typical row of) the value of a table expression AS some name ("table alias", "correlation name").
(It turns out that because of details of the grammar typos are less problematic if we use AS in SELECT clauses but don't use AS in FROM clauses.)
There are other uses of AS. The context also determines what they mean, and they also correspond to using using a name to refer to something.
In technical contexts it turns out not to be helpful to try to make sense of what something means based on the everyday meanings of technical terms, including making sense of what a thing is based on its name. The SQL language designers [sic] didn't choose to always have either <expression> AS <name> or <name> AS <expression>. That is just how it is. That is just how you write stuff to get your program to do stuff to stuff. (Accepted but more modern principles of computer language design do suggest more regular notations.)