PostgreSQL 9.6 with pgAdmin 4 - numeric data type - pgadmin-4

I have columns with numeric(5,2) data type.
When the actual data is 1.25, it displays correctly as 1.25.
When the actual data is 1.00, it displays as 1.
Can anyone tell me why? Is there something that I need to set to have it so the two decimal 0's display?

I think this may be an issue specific to pgadmin4. Consider:
> createdb test
> psql -d test
psql (9.4.9)
Type "help" for help.
test=# create table mytest(id serial not null primary key, name varchar(30),salary numeric(5,2));
CREATE TABLE
test=# select * from mytest;
id | name | salary
----+------+--------
(0 rows)
test=# insert into mytest(name,salary) values('fred',10.3);
INSERT 0 1
test=# insert into mytest(name,salary) values('mary',11);
INSERT 0 1
test=# select * from mytest;
id | name | salary
----+------+--------
1 | fred | 10.30
2 | mary | 11.00
(2 rows)
test=# select salary from mytest where name = 'mary';
salary
--------
11.00
(1 row)
This example is with version 9.4 as you can see, but would be a simple test to see if the problem is with 9.6 or pgadmin4. In pgadmin3 the value is displayed correctly with decimal places.
Last time I tried pgadmin4 it had a number of annoying issues that sent me scurrying back to pgadmin3 for the time being. However there is a list where you can seek confirmation of the bug: https://redmine.postgresql.org/projects/pgadmin4

This is a bug with pgAdmin4 and already reported https://redmine.postgresql.org/issues/2039

Related

SQL Consecutive Sequence Number gets messed up with ORDER BY

I am working on Windows Form Application and it accesses database in SQL Server 2014. I have EmployeeTable which I retrieve data from, and display all the records in DataGridView. In this table, I have a column SequenceID, which basically increments from 1 up to the number of records in this table, but this is not the same as AUTO INCREMENT in that SequenceID gets updated each time the table is modified, and keeps the numerical order no matter how many times new records get inserted or some records are deleted. For example, if the data looks like
SequenceID | Name
1 | John
2 | Mary
3 | Robert
and Mary is removed, then the resulting table needs to look like
SequenceID | Name
1 | John
2 | Robert
In order to achieve this, I used the best answer by zombat from Update SQL with consecutive numbering, and it was working great until I used ORDER BY expression.
This EmployeeTable also has DateAdded column, containing the date when the record was inserted. I need to display all records ordered by this DateAdded column, with the oldest record shown at the top and the newest at the bottom in addition to the correct SequenceID order. However, it gets messed up when a record is deleted, and a new one is inserted.
If I insert 3 records like,
SequenceID | Name | DateAdded
1 | John | 9/25/2017
2 | Mary | 9/26/2017
3 | Robert | 9/27/2017
and remove Mary, it becomes
SequenceID | Name | DateAdded
1 | John | 9/25/2017
2 | Robert | 9/27/2017
and this is good so far. However, if I add another record Tommy on, say, 9/28/2017, which should be added at the bottom because it is the newest, it results in something like,
SequenceID | Name | DateAdded
1 | John | 9/25/2017
3 | Robert | 9/27/2017
2 | Tommy | 9/28/2017
The ORDER BY is working fine, but it messes up the SequenceID, and I am not sure why this is happening. All I am doing is,
SELECT *
FROM EmployeeTable
ORDER BY DateAdded
I tried placing zombat's SQL command both before and after this SQL command, but neither worked. It seems to me like when I delete a row, the row has an invisible spot, and a new record is inserted in there.
Is there any way to fix this so I can order the records by DateAdded and still have the SequenceID working correctly?
If you need id for GUI (presentation only) you could use:
SELECT ROW_NUMBER() OVER(ORDER BY DateAdded) AS sequenceId, Name, DateAdded
FROM EmployeeTable
ORDER BY DateAdded;
EDIT:
I am trying to update the SequenceID, but it is not getting updated
You should not try to reorder your table every time. It doesn't make sense.

How to label result tables in multiple SELECT output

I wrote a simple dummy procedure to check the data that saved in the database. When I run my procedure it output the data as below.
I want to label the tables. Then even a QA person can identify the data which gives as the result. How can I do it?
**Update : ** This procedure is running manually through Management Studios. Nothing to do with my application. Because all I want to check is whether the data has inserted/updated properly.
For better clarity, I want to show the table names above the table as a label.
Add another column to the table, and name it so it will be distinguished by who reads them :)
Select 'Employee' as TABLE_NAME, * from Employee
Output will look like this:
| TABLE_NAME | ID | Number | ...
------------------------------
| Employee | 1 | 123 | ...
Or you can call the column 'Employee'
SELECT 'Employee' AS 'Employee', * FROM employee
The output will look like this:
| Employee | ID | Number | ...
------------------------------
| Employee | 1 | 123 | ...
Add an extra column, whiches name (not value!) is the label.
SELECT 'Employee' AS "Employee", e.* FROM employee e
The output will look like this:
| Employee | ID | Number | ...
------------------------------
| Employee | 1 | 123 | ...
By doing so, you will see the label, even if the result does not contain rows.
I like to stick a whole nother result set that looks like a label or title between the result sets with real data.
SELECT 0 AS [Our Employees:]
WHERE 1 = 0
-- Your first "Employees" query goes here
SELECT 0 AS [Our Departments:]
WHERE 1 = 0
-- Now your second real "Departments" query goes here
-- ...and so on...
Ends up looking like this:
It's a bit looser-formatted with more whitespace than I like, but is the best I've come up with so far.
Unfortunately there is no way of labeling any SELECT query output in SQL Server or SSMS. The very similar thing was once needed in my experience a few years ago. We settled for using a work around:
Adding another table which contains the list of table aliases.
Here is what we did:
We appended the list of tables with another table in the beginning of the data set. So the first Table will look as follows:
Name
Employee
Department
Courses
Class
Attendance
In c# while reading the tables, you can iterate through the first table first and assign TableName to all tables in the DataSet further.
This is best done using Reporting Services and creating a simple report. You can then email this report daily if you wish.

SQL Server 2008 exec stored procedure on 3rd strike

I've been asked to create a process that triggers a stored procedure when an employee hits their 3rd strike. The strikes relate to absence, so if an employee is off 3 times in a 3 month period it hits the trigger.
But... this only applies to single instances of absence, so if a person is off; for example on the 11/01/2016, 12/01/2016 & 13/01/2016 then this is one instance. Meaning I can't do a count on the number of days off sick.
Data I have available and is a fixed process I can't update:
Date | EmpID | EmpName
01/01/2016 | JS01 | John Spartan
02/01/2016 | JS01 | John Spartan
03/01/2016 | JS01 | John Spartan
08/01/2016 | JS01 | John Spartan
19/02/2016 | JS01 | John Spartan
12/02/2016 | JS01 | John Spartan
Based on the above there are more than 2 instances. So this would trigger the procedure
IF EXISTS (<Query Here>)
BEGIN
EXEC usp_ThreeStrikes
END
Is there a way to do this in T-SQL?
If you can't add columns to help query with the task (eg. InstanceID query would group by to find out number of instances), I think best solution would be to create aggregate CLR function for the task.
https://msdn.microsoft.com/en-us/library/ms131056.aspx
You can try the below approach:
Add an additional column to your table to differentiate if the record should be considered for next strike or not (means after 1 instance, it should not be considered the 2nd time)
Create a SQL Update Trigger to call the procedure, based on the below condition:
Get the records whose column is considered for next strike (same column what you have created in first step)
For those particular records check the count if its greater or equal to 3 and call the stored procedure
For those particular records, update the additional column (created in step 1) to not consider it for the subsequent strikes
Hope this helps.
Here you have a query that lists the empid's that were absent three or more times per quarter. You can modify this query in your trigger to only select in the empids/quarters that are present in the inserted table in your trigger.
PS: I've added some random absences to show that the query only selectes when the number of absences is three or more.
CREATE TABLE #absences(dt DATE,empid NVARCHAR(128),empname NVARCHAR(128));
INSERT INTO #absences(dt,empid,empname)VALUES
('20151212','JS02','John Spartan2'),
('20151213','JS02','John Spartan2'),
('20151010','JS01','John Spartan'),
('20151011','JS01','John Spartan'),
('20151217','JS02','John Spartan2'),
('20151219','JS02','John Spartan2'),
('20160101','JS01','John Spartan'),
('20160102','JS01','John Spartan'),
('20160103','JS01','John Spartan'),
('20160108','JS01','John Spartan'),
('20160201','JS02','John Spartan2'),
('20160203','JS02','John Spartan2'),
('20160219','JS01','John Spartan'),
('20160212','JS01','John Spartan');
SELECT
empid,
[quarter]=DATEADD(QUARTER,DATEDIFF(QUARTER,0,o.dt),0)
FROM
#absences AS o
WHERE
NOT EXISTS (
SELECT 1
FROM #absences AS i
WHERE i.empid=o.empid AND
DATEDIFF(QUARTER,0,i.dt)=DATEDIFF(QUARTER,0,o.dt) AND
i.dt=DATEADD(DAY,-1,o.dt)
)
GROUP BY
empid,
DATEDIFF(QUARTER,0,o.dt)
HAVING
COUNT(*)>=3;
DROP TABLE #absences;
Result:
+-------+-------------------------+
| empid | quarter |
+-------+-------------------------+
| JS02 | 2015-10-01 00:00:00.000 |
| JS01 | 2016-01-01 00:00:00.000 |
+-------+-------------------------+

Formatting External tables in Greenplum (PostgreSQL)

I want to load a plain file into Greenplum database using external tables.
Can I specify input format for timestamps/date/time fields? (If you know the answer for PostgreSQL, please reply as well)
For example, with Oracle I can use DATE_FORMAT DATE MASK 'YYYYMMDD' to tell how to parse the date. For Netezza I can specify DATESTYLE 'YMD'. For Greenplum I cannot find the answer. I can describe fields as char, and then parse them during the load, but this is an ugly workaround.
Here is my tentative code:
CREATE EXTERNAL TABLE MY_TBL (X date, Y time, Z timestamp )
LOCATION (
'gpfdist://host:8001/file1.txt',
'gpfdist://host:8002/file2.txt'
) FORMAT 'TEXT' (DELIMITER '|' NULL '')
It appears that you can:
SET DATESTYLE = 'YMD';
before SELECTing from the table. This will affect the interpretation of all dates, though, not just those from the file. If you consistently use unambiguous ISO dates elsewhere that will be fine, but it may be a problem if (for example) you need to also accept 'D/M/Y' date literals in the same query.
This is specific to GreenPlum's CREATE EXTERNAL TABLE and does not apply to SQL-standard SQL/MED foreign data wrappers, as shown below.
What surprises me is that PostgreSQL proper (which does not have this CREATE EXTERNAL TABLE feature) always accepts ISO-style YYYY-MM-DD and YYYYMMDD dates, irrespective of DATESTYLE. Observe:
regress=> SELECT '20121229'::date, '2012-12-29'::date, current_setting('DateStyle');
date | date | current_setting
------------+------------+-----------------
2012-12-29 | 2012-12-29 | ISO, MDY
(1 row)
regress=> SET DateStyle = 'DMY';
SET
regress=> SELECT '20121229'::date, '2012-12-29'::date, current_setting('DateStyle');
date | date | current_setting
------------+------------+-----------------
2012-12-29 | 2012-12-29 | ISO, DMY
(1 row)
... so if GreenPlum behaved the same way, you should not need to do anything to get these YYYYMMDD dates to be read correctly from the input file.
Here's how it works with a PostgreSQL file_fdw SQL/MED foreign data wrapper:
CREATE EXTENSION file_fdw;
COPY (SELECT '20121229', '2012-12-29') TO '/tmp/dates.csv' CSV;
SET DateStyle = 'DMY';
CREATE SERVER csvtest FOREIGN DATA WRAPPER file_fdw;
CREATE FOREIGN TABLE csvtest (
date1 date,
date2 date
) SERVER csvtest OPTIONS ( filename '/tmp/dates.csv', format 'csv' );
SELECT * FROM csvtest ;
date1 | date2
------------+------------
2012-12-29 | 2012-12-29
(1 row)
The CSV file contents are:
20121229,2012-12-29
so you can see that Pg will always accept ISO dates for CSV, irrespective of datestyle.
If GreenPlum doesn't, please file a bug. The idea of DateStyle changing the way a foreign table is read after creation is crazy.
Yes you can.
You do this by specifying the field in the external table to be of type text. Then, use a transformation in the insert statement. You can also use gpload and define the transformation. Both solutions are similar to the solution described above.
Here is a simple file with an integer and a date expressed as year month day, separated by a space:
date1.txt
1|2012 10 12
2|2012 11 13
Start gpfdist:
gpfdist -p 8010 -d ./ -l ./gpfdist.log &
Use psql to create the external table, the target table, and load the data:
psql test
test=# create external table ext.t2( i int, d text )
location ('gpfdist://walstl-mbp.local:8010/date1.txt')
format 'TEXT' ( delimiter '|' )
;
test=# select * from ext.t2; i | d
---+------------
1 | 2012 10 12
2 | 2012 11 13
(2 rows)
Now, create the table that the data will be loaded into:
test=# create table test.t2 ( i int, d date )
;
And,load the table:
test=# insert into test.t2 select i, to_date(d,'YYYY MM DD') from ext.t2 ;
test=# select * from test.t2;
i | d
---+------------
1 | 2012-10-12
2 | 2012-11-13

Select Query is not working with WHERE clasue when there is a space in Column Name

I have got SQL Server database in which Table column name have spaces. For example I have a Table something like this:
ID| First Name| Last Name|Birth Date
1 | Wasim | Akram | 01-01-2000
2 | Saeed | Anwer | 01-01-2001
Now When I use a following query(column name with space) I get empty result:
SELECT * FROM table WHERE 'First Name'='Wasim'
And when I use following query(column name with no space) I get one accurate result:
SELECT * FROM table WHERE ID='1'
I am using SQL Server 2005
Thanks
You need wrap the column name in square brackets
SELECT * FROM table WHERE [First Name]='Wasim'

Resources