Foxpro VS SQL Logic - tsql

I couldn't think of a better title. If you have any suggestions, feel free to edit the title of my post.
I have a foxpro query that looks like this:
Sele
a.plan_enddt as enddt, a.plrevno, a.keyfld, "PLAN " as source ;
from a_plan a inner join c_temp1a_pre b ;
on a.keyfld=b.keyfld and a.plrevno=b.plrevno ;
into cursor c_temp1a ;
group by a.keyfld ;
where a.plan_enddt>=date1 ;
What I am trying to do is translate from foxpro into T-SQL.
Wouldn't this foxpro statement fail because only 1 column is listed in the group by?
Edit:
I am not looking for a solution to fixing my foxpro statement
In TSQL, you can't just group by 1 column if you have multiple in the select statement, even if you aren't using an aggregate function.
Is this also true in Foxpro?

You could use:
Select MIN(a.plan_enddt) as enddt, MIN(a.plrevno), a.keyfld, 'PLAN ' as [source]
from a_plan a
inner join c_temp1a_pre b
on a.keyfld=b.keyfld
and a.plrevno=b.plrevno
where a.plan_enddt>=date1
group by a.keyfld ;
"I am not looking for a solution to fixing my foxpro statement"
This is the same case as between MySQL and PostgreSQL: Group by clause in mySQL and postgreSQL, why the error in postgreSQL?
SQL99 and later permits such nonaggregates per optional feature T301 if they are functionally dependent on GROUP BY columns
T-SQL 2.1.2.221 T301, Functional dependencies

It looks as bug in Foxpro (Visual Foxpro 8 and earlier) to accept such invalid group by clause. All fields listed in select that are not aggregate values should be also part of group by fields.
Like this:
select
min(a.plan_enddt) as enddt, min(a.plrevno) as plrevno, a.keyfld, "PLAN " as source
from a_plan a inner join c_temp1a_pre b
on a.keyfld=b.keyfld and a.plrevno=b.plrevno
into cursor c_temp1a
group by a.keyfld
where a.plan_enddt>=date1 ;
or this:
select
a.plan_enddt as enddt, a.plrevno, a.keyfld, "PLAN " as source
from a_plan a inner join c_temp1a_pre b
on a.keyfld=b.keyfld and a.plrevno=b.plrevno
into cursor c_temp1a
group by a.keyfld, a.plan_enddt, a.plrevno
where a.plan_enddt>=date1 ;
But in this case you can get more than one record, there is group by few fields.

Related

Aginity Netezza macro containing a list

I would like to put a list of names in my Aginity Netezza macro. For instance, I would like to be able to repeatedly use the list ("Adam", "Bill", "Cynthia", "Dick", "Ella", "Fanny") in my future queries, e.g. in WHERE clauses.
My questions are:
(1) Is there a limit to how many characters I can put inside the "Value" window of the Query Parameters Editor?
(2) Is there a way to make this work without using a macro? For instance, predefining this list somewhere?
I would put the list into a (temporary) table, and simply join to it when necessasary:
Create temp table names as
Select ‘Adam’::varchar(50)
Union all Select ‘Bill’::varchar(50)
Union all Select ‘Cynthia’::varchar(50)
Union all Select ‘Dick’::varchar(50)
Union all Select ‘Ella’::varchar(50)
Union all Select ‘Fanny’
;
Select x.a,x.b
from x
where x.name in (select * from Names)
;
Select
case
when x.name in (select * from Names)
then ‘Special’
Else ‘Other’
End as NameGrp,
Count(*) as size,
Sum(income) as TotalIncome
Group by NameGrp
Order by size desc
;
Alternatively netezza has an extension toolkit that enables ARRAY data types, but especially the first query will not perform well if you use it for that purpose. Interested? See here: https://www.ibm.com/support/knowledgecenter/en/SSULQD_7.2.1/com.ibm.nz.sqltk.doc/c_sqlext_array.html or google for examples

Query Oracle SqlDeveloper

I want to write a SELECT statement to create a list of jobs containing the job_title and the mean value of the two fields MIN_SALARY and MAX_SALARY sorted from the highest mean value to the lowest.
I wrote this:
select job_title, MAX_SALARY, MIN_SALARY, count(*)
from HR.EMPLOYEES, HR.JOBS
order by count(*) desc
group by j.job_title;
but it gives error:
ORA-00933: SQL command not properly ended 00933. 00000 - "SQL command not properly ended"
I think that you should have this query
select job_title, MAX_SALARY, MIN_SALARY, count(*)
from HR.EMPLOYEES, HR.JOBS
group by job_title
order by count(*) desc
I have reordered the clauses and removed the spurious j
See - select

Error while using regexp_split_to_table (Amazon Redshift)

I have the same question as this:
Splitting a comma-separated field in Postgresql and doing a UNION ALL on all the resulting tables
Just that my 'fruits' column is delimited by '|'. When I try:
SELECT
yourTable.ID,
regexp_split_to_table(yourTable.fruits, E'|') AS split_fruits
FROM yourTable
I get the following:
ERROR: type "e" does not exist
Q1. What does the E do? I saw some examples where E is not used. The official docs don't explain it in their "quick brown fox..." example.
Q2. How do I use '|' as the delimiter for my query?
Edit: I am using PostgreSQL 8.0.2. unnest() and regexp_split_to_table() both are not supported.
A1
E is a prefix for Posix-style escape strings. You don't normally need this in modern Postgres. Only prepend it if you want to interpret special characters in the string. Like E'\n' for a newline char.Details and links to documentation:
Insert text with single quotes in PostgreSQL
SQL select where column begins with \
E is pointless noise in your query, but it should still work. The answer you are linking to is not very good, I am afraid.
A2
Should work as is. But better without the E.
SELECT id, regexp_split_to_table(fruits, '|') AS split_fruits
FROM tbl;
For simple delimiters, you don't need expensive regular expressions. This is typically faster:
SELECT id, unnest(string_to_array(fruits, '|')) AS split_fruits
FROM tbl;
In Postgres 9.3+ you'd rather use a LATERAL join for set-returning functions:
SELECT t.id, f.split_fruits
FROM tbl t
LEFT JOIN LATERAL unnest(string_to_array(fruits, '|')) AS f(split_fruits)
ON true;
Details:
What is the difference between LATERAL and a subquery in PostgreSQL?
PostgreSQL unnest() with element number
Amazon Redshift is not Postgres
It only implements a reduced set of features as documented in its manual. In particular, there are no table functions, including the essential functions unnest(), generate_series() or regexp_split_to_table() when working with its "compute nodes" (accessing any tables).
You should go with a normalized table layout to begin with (extra table with one fruit per row).
Or here are some options to create a set of rows in Redshift:
How to select multiple rows filled with constants in Amazon Redshift?
This workaround should do it:
Create a table of numbers, with at least as many rows as there can be fruits in your column. Temporary or permanent if you'll keep using it. Say we never have more than 9:
CREATE TEMP TABLE nr9(i int);
INSERT INTO nr9(i) VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9);
Join to the number table and use split_part(), which is actually implemented in Redshift:
SELECT *, split_part(t.fruits, '|', n.i) As fruit
FROM nr9 n
JOIN tbl t ON split_part(t.fruits, '|', n.i) <> ''
Voilá.

Create a new table out of an existing one

I am having this table of words from multiple files. I want to count how many files each word shows. I can that with the piece of code below. But when I nest it with the CREATE TABLE statement, it won't work. The second piece of code below is the error code.
SELECT WORD, COUNT(*) FROM (select DISTINCT ABSTRACTID, WORD FROM NSFABSTRACTS)
GROUP BY WORD ORDER BY COUNT(*) DESC
CREATE TABLE DOC_FREQ (WORD, TOTALCOUNT) AS
(
SELECT WORD, COUNT(*) FROM (select DISTINCT ABSTRACTID, WORD FROM NSFABSTRACTS)
GROUP BY WORD ORDER BY COUNT(*));
Here is the error message:
SQL Error: ORA-00907: missing right parenthesis
00907. 00000 - "missing right parenthesis"
*Cause:
*Action:
Can anyone suggest how to create this table? Thanks.
You cannot use order by when you have the query enclosed in parentheses; at least if that clause is also within the parentheses:
create table t42 as (select * from dual order by dummy);
SQL Error: ORA-00907: missing right parenthesis
It is allowed outside:
create table t42 as (select * from dual) order by dummy;
table T42 created.
You can remove the parentheses as they aren't needed at all here:
create table t42 as select * from dual order by dummy;
table T42 created.
Or remove the order by, since an order by in the create statement usually makes little difference and doesn't affect how the data is retrieved:
create table t42 as (select * from dual);
table T42 created.
Or preferably for my tastes, both:
create table t42 as select * from dual;
table T42 created.

IBM db2 union query bad results

When I execute this query in SQL Server which calls to IBM,
Select * from openquery(ibm,'
Select COST_AMT,'Query1' as Query
from table
where clause
with ur;
')
union
Select * from openquery(ibm,'
Select COST_AMT,'Query2' as Query
from table
different where clause
with ur;
')
I get different results in the union query than when I execute them separately and bring the results in together. I have tried the union query inside the openquery so I believe this is an IBM thing. The results appear to be a distinct selection of COST_AMT sorted by lowest to highest.
ie:
1,Query1
2,Query1
3,Query1
1,Query2
2,Query2
3,Query2
but the data is actually like this:
1,Query1
1,Query1
1,Query1
2,Query1
2,Query1
3,Query1
1,Query2
1,Query2
1,Query2
2,Query2
2,Query2
3,Query1
Am I missing something about the ibm union query? I realize I could sum and get the answer, (which is what I plan no doing) but I want to know more about why this is happening.
This has nothing to do with "ibm" or "db2" -- the SQL UNION operator removes duplicates. To retain duplicates use UNION ALL.