Postgresql: HAVING statement that skips rows which are null or empty? - postgresql

Is there any way to skip rows that are null or empty? I could use some help with sorting the output of a subtable. My having statement is returning an error I can’t fix.
It returns the error: ERROR: invalid input syntax for integer: " "
This seems to be because some rows in my table will have either null values or be empty and the having statement is getting hung up there.
Here is the full query
SELECT
count(job),
year,
zipcode
FROM
(
SELECT
substring (cast(dobjobs.prefilingdate AS varchar), '^\d\d\d\d') AS year,
dobjobs.job,
dobjobs.bbl,
pluto_17v1.zipcode
FROM
dobjobs
JOIN pluto_17v1 ON dobjobs.bbl = pluto_17v1.bbl
GROUP BY
dobjobs.prefilingdate,
dobjobs.bbl,
pluto_17v1.zipcode,
dobjobs.job
ORDER BY
year
) AS sub
GROUP BY
year, zipcode
HAVING
CAST( zipcode AS int ) IN (10039, 10039, 10026, 10030, 10037, 10027, 10032, 10033, 10040, 10034, 10031)
ORDER BY
year;

Related

It can't calculate count(*) in a query onto DB2 database

I want to do a count(*) of the number of a rows fom a DB2 database.
The basic query is the following:
select
SUBSTR("Request_Detail",LOCATE('/',"Request_Detail")+1,LOCATE('/',"Request_Detail",LOCATE('/',"Request_Detail")+1)-LOCATE('/',"Request_Detail"))
from "Request_Analisys"
WHERE
"Sample_Date_and_Time">=1200323230000000 and "Sample_Date_and_Time"<1200332300000000
and "Request_Detail" <> '[Summary]'
and "Request_Detail" not like 'WS:%'
Now I'd like to do a count(*) of the resulting rows, but if I do a query like this:
select
count(*),
SUBSTR("Request_Detail",LOCATE('/',"Request_Detail")+1,LOCATE('/',"Request_Detail",LOCATE('/',"Request_Detail")+1)-LOCATE('/',"Request_Detail"))
from "Request_Analisys"
WHERE
"Sample_Date_and_Time">=1200323230000000 and "Sample_Date_and_Time"<1200332300000000
and "Request_Detail" <> '[Summary]'
and "Request_Detail" not like 'WS:%'
It gives the error:
18:51:58 FAILED [SELECT - 0 rows, 0.032 secs] 1) [Code: -119, SQL State: 42803] An expression starting with "Request_Detail" specified in a SELECT clause, HAVING clause, or ORDER BY clause is not specified in the GROUP BY clause or it is in a SELECT clause, HAVING clause, or ORDER BY clause with a column function and no GROUP BY clause is specified.. SQLCODE=-119, SQLSTATE=42803, DRIVER=4.22.29
2) [Code: -727, SQL State: 56098] An error occurred during implicit system action type "2". Information returned for the error includes SQLCODE "-119", SQLSTATE "42803" and message tokens "Request_Detail".. SQLCODE=-727, SQLSTATE=56098, DRIVER=4.22.29
How could I do to get the count of the rows?
Which Request_Detail line's substr would you think it shows after the count?
If you count the lines, the result set will be a single line, and using any columns in it makes no sense.
If you want multiple lines, with a count for each found substr, you need to GROUP BY this substr.
This may work...
select
count(
SUBSTR("Request_Detail"
,LOCATE('/',"Request_Detail")+1
,LOCATE('/',"Request_Detail",LOCATE('/',"Request_Detail")+1)
-LOCATE('/',"Request_Detail")))
)
from "Request_Analisys"
WHERE
"Sample_Date_and_Time">=1200323230000000 and "Sample_Date_and_Time"<1200332300000000
and "Request_Detail" <> '[Summary]'
and "Request_Detail" not like 'WS:%'
But if not this should..
with cte as (
select
SUBSTR("Request_Detail"
,LOCATE('/',"Request_Detail")+1
,LOCATE('/',"Request_Detail",LOCATE('/',"Request_Detail")+1)
-LOCATE('/',"Request_Detail"))) as mydetail
from "Request_Analisys"
WHERE
"Sample_Date_and_Time">=1200323230000000 and "Sample_Date_and_Time"<1200332300000000
and "Request_Detail" <> '[Summary]'
and "Request_Detail" not like 'WS:%'
)
select count(*) from cte
I suggest you use REGEXP_EXTRACT to pick what you want out of your "Request_Detail" column. This is more flexable than using SUBSTR and LOCATE, and will avoid the statement was not executed because a numeric argument of a scalar function is out of range.. error
e.g
select
REGEXP_EXTRACT("Request_Detail",'.*/(.+/)',1,1,'',1)
, SUBSTR("Request_Detail",LOCATE('/',"Request_Detail")+1,LOCATE('/',"Request_Detail",LOCATE('/',"Request_Detail")+1)-LOCATE('/',"Request_Detail"))
FROM TABLE(VALUES('aaaa/bbbb/ccc')) AS T("Request_Detail")
returns
1 |2
------|-----
bbbb/ |bbbb/
so, you could then do this
SELECT
COUNT(*)
, REGEXP_EXTRACT("Request_Detail",'.*/(.+/)',1,1,'',1)
FROM
"Request_Analisys"
GROUP BY
REGEXP_EXTRACT("Request_Detail",'.*/(.+/)',1,1,'',1)
for example

How to get the count of records returned by teradata sql griup by query

I have a condition where I need to check number of rows returned by select query in Teradata.
My query looks like below
select
PDate ,Risk ,BName ,BNumber ,
ONumber ,OnNumber ,ID_CD ,Entity ,
AU ,RType, count (*)
from Load_one.import_test
group by 1,2,3,4,5,6,7,8,9,10
having count (*) > 1;
So I would like to know the count of rows it returns. I tried something like below
Select Count(*)
From ( select
PDate ,Risk ,BName ,BNumber ,
ONumber ,OnNumber ,ID_CD ,Entity ,
AU ,RType, count (*)
from Load_one.import_test
group by 1,2,3,4,5,6,7,8,9,10
having count (*) > 1;
) as temp
It returning an error: select failed 3707 expected something like an 'EXCEPT' keyword or an 'UNION' keyword or a 'MINUS' keyword between an integer and ;
Please help me.

invalid input syntax for integer: "1" postgresql

PostgreSql gives me this error when i try to cast a TEXT colum to a integer.
select pro_id::integer from mmp_promocjas_tmp limit 1;
This colum contains only digits, valid integer. How can "1" be invalid integer?
select pro_id, length(pro_id) ,length(trim(pro_id)) from mmp_promocjas_tmp limit 1;
outputs:
1 | 2 | 2
Query select pro_id from mmp_promocjas_tmp where trim(pro_id) = '1' shows nothing.
I tried to remove whitespaces, without no result:
select pro_id from mmp_promocjas_tmp where regexp_replace(trim(pro_id), '\s*', '', 'g')
There are probably spurious invisible contents in the column.
To make them visible, try a query like this:
select pro_id, c,lpad(to_hex(ascii(c)),4,'0') from (
select pro_id,regexp_split_to_table(pro_id,'') as c
from (select pro_id from mmp_promocjas_tmp limit 10) as s
) as g;
This will show the ID and each character its contains, both as a character and as its hexadecimal code in the repertoire.

Column is of type timestamp without time zone but expression is of type character

I'm trying to insert records on my trying to implement an SCD2 on Redshift
but get an error.
The target table's DDL is
CREATE TABLE ditemp.ts_scd2_test (
id INT
,md5 CHAR(32)
,record_id BIGINT IDENTITY
,from_timestamp TIMESTAMP
,to_timestamp TIMESTAMP
,file_id BIGINT
,party_id BIGINT
)
This is the insert statement:
INSERT
INTO ditemp.TS_SCD2_TEST(id, md5, from_timestamp, to_timestamp)
SELECT TS_SCD2_TEST_STAGING.id
,TS_SCD2_TEST_STAGING.md5
,from_timestamp
,to_timestamp
FROM (
SELECT '20150901 16:34:02' AS from_timestamp
,CASE
WHEN last_record IS NULL
THEN '20150901 16:34:02'
ELSE '39991231 11:11:11.000'
END AS to_timestamp
,CASE
WHEN rownum != 1
AND atom.id IS NOT NULL
THEN 1
WHEN atom.id IS NULL
THEN 1
ELSE 0
END AS transfer
,stage.*
FROM (
SELECT id
FROM ditemp.TS_SCD2_TEST_STAGING
WHERE file_id = 2
GROUP BY id
HAVING count(*) > 1
) AS scd2_count_ge_1
INNER JOIN (
SELECT row_number() OVER (
PARTITION BY id ORDER BY record_id
) AS rownum
,stage.*
FROM ditemp.TS_SCD2_TEST_STAGING AS stage
WHERE file_id IN (2)
) AS stage
ON (scd2_count_ge_1.id = stage.id)
LEFT JOIN (
SELECT max(rownum) AS last_record
,id
FROM (
SELECT row_number() OVER (
PARTITION BY id ORDER BY record_id
) AS rownum
,stage.*
FROM ditemp.TS_SCD2_TEST_STAGING AS stage
)
GROUP BY id
) AS last_record
ON (
stage.id = last_record.id
AND stage.rownum = last_record.last_record
)
LEFT JOIN ditemp.TS_SCD2_TEST AS atom
ON (
stage.id = atom.id
AND stage.md5 = atom.md5
AND atom.to_timestamp > '20150901 16:34:02'
)
) AS TS_SCD2_TEST_STAGING
WHERE transfer = 1
and to short things up, I am trying to insert 20150901 16:34:02 to from_timestamp and 39991231 11:11:11.000 to to_timestamp.
and get
ERROR: 42804: column "from_timestamp" is of type timestamp without time zone but expression is of type character varying
Can anyone please suggest how to solve this issue?
Postgres isn't recognizing 20150901 16:34:02 (your input) as a valid time/date format, so it assumes it's a string.
Use a standard date format instead, preferably ISO-8601. 2015-09-01T16:34:02
SQLFiddle example
Just in case someone ends up here trying to insert into a postgresql a timestamp or a timestampz from a variable in groovy or Java from a prepared statement and getting the same error (as I did), I managed to do it by setting the property stringtype to "unspecified". According to the documentation:
Specify the type to use when binding PreparedStatement parameters set
via setString(). If stringtype is set to VARCHAR (the default), such
parameters will be sent to the server as varchar parameters. If
stringtype is set to unspecified, parameters will be sent to the
server as untyped values, and the server will attempt to infer an
appropriate type. This is useful if you have an existing application
that uses setString() to set parameters that are actually some other
type, such as integers, and you are unable to change the application
to use an appropriate method such as setInt().
Properties props = [user : "user", password: "password",
driver:"org.postgresql.Driver", stringtype:"unspecified"]
def sql = Sql.newInstance("url", props)
With this property set, you can insert a timestamp as a string variable without the error raised in the question title. For instance:
String myTimestamp= Instant.now().toString()
sql.execute("""INSERT INTO MyTable (MyTimestamp) VALUES (?)""",
[myTimestamp.toString()]
This way, the type of the timestamp (from a String) is inferred correctly by postgresql. I hope this helps.
Inside apache-tomcat-9.0.7/conf/server.xml
Add "?stringtype=unspecified" to the end of url address.
For example:
<GlobalNamingResources>
<Resource name="jdbc/??" auth="Container" type="javax.sql.DataSource"
...
url="jdbc:postgresql://127.0.0.1:5432/Local_DB?stringtype=unspecified"/>
</GlobalNamingResources>

Dynamic pivot - how to obtain column titles parametrically?

I wish to write a Query for SAP B1 (t-sql) that will list all Income and Expenses Items by total and month by month.
I have successfully written a Query using PIVOT, but I do not want the column headings to be hardcoded like: Jan-11, Feb-11, Mar-11 ... Dec-11.
Rather I want the column headings to be parametrically generated, so that if I input:
--------------------------------------
Query - Selection Criteria
--------------------------------------
Posting Date greater or equal 01.09.10
Posting Date smaller or equal 31.08.11
[OK] [Cancel]
the Query will generate the following columns:
Sep-10, Oct-10, Nov-10, ..... Aug-11
I guess DYNAMIC PIVOT can do the trick.
So, I modified one SQL obtained from another forum to suit my purpose, but it does not work. The error message I get is Incorrect Syntax near 20100901.
Could anybody help me locate my error?
Note: In SAP B1, '[%1]' is an input variable
Here's my query:
/*Section 1*/
DECLARE #listCol VARCHAR(2000)
DECLARE #query VARCHAR(4000)
-------------------------------------
/*Section 2*/
SELECT #listCol =
STUFF(
( SELECT DISTINCT '],[' + CONVERT(VARCHAR, MONTH(T0.RefDate), 102)
FROM JDT1
FOR XML PATH(''))
, 1, 2, '') + ']'
------------------------------------
/*Section 3*/
SET #query = '
SELECT * FROM
(
SELECT
T0.Account,
T1.GroupMask,
T1.AcctName,
MONTH(T0.RefDate) as [Month],
(T0.Debit - T0.Credit) as [Amount]
FROM dbo.JDT1 T0
JOIN dbo.OACT T1 ON T0.Account = T1.AcctCode
WHERE
T1.GroupMask IN (4,5,6,7) AND
T0.[Refdate] >= '[%1]' AND
T0.[Refdate] <= '[%2]'
) S
PIVOT
(
Sum(Amount)
FOR [Month] IN ('+#listCol+')
) AS pvt
'
--------------------------------------------
/*Section 4*/
EXECUTE (#query)
I don't know SAP, but a couple of things spring to mind:
It looks like you want #listCol to contain a collection of numbers within square brackets, for example [07],[08],[09].... However, your code appears not to put a [ at the start of this string.
Try replacing the lines
T0.[Refdate] >= '[%1]' AND
T0.[Refdate] <= '[%2]'
with
T0.[Refdate] >= ''[%1]'' AND
T0.[Refdate] <= ''[%2]''
(I also added a space before the AND in the first of these two lines while I was editing your question.)