search a keyword in postgresql json field - sql

I am currently using postgres 9.3.3
Following is how my table looks like -
Column | Type | Modifiers | Storage | Stats target | Description
--------------------+--------------------------+--------------------------------------------------------------------+----------+--------------+-------------
id | integer | not null default nextval('playerbase_palyerdata_id_seq'::regclass) | plain | |
date_joined | timestamp with time zone | not null | plain | |
belongs_to_camp_id | integer | not null | plain | |
belongs_to_coach_id | integer | not null | plain | |
json_kvps | character varying(2000) | not null | extended | |
One sample data is as follows -
id | date_joined | belongs_to_camp_id | belongs_to_coach_id | json_kvps
1 | 2014-03-07 18:10:45.824749+05:30 | 1 | 1 | {"alumnicode": "2003360009", "emailusername": "aaron#hotmail.com", "altemail": "", "salutation": "Mrs", "fname": "Aaron", "mname": "V", "lname": "Schwartz", "fullname": "Aaraon M Scwartz", "programmename": "MEP", "batchyearin": "2003"}
Now I want to search the entire table, and find a user with "emailusername":"aaron#hotmail.com"
As mentioned here -
http://www.postgresql.org/docs/current/static/functions-json.html
I try to write a query as follows -
SELECT * FROM playerbase_playerdata WHERE json_kvps->>'emailusername' = 'aaron#hotmail.com';
I was expecting a column as above, instead I got the following error -
ERROR: operator does not exist: character varying ->> unknown
LINE 1: ...ELECT * FROM memberbase_memberdata WHERE json_kvps->>'emailu...
^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Could someone please tell me, what am I missing?

Feature like this exists only from PostgreSQL release 9.3.
So, unfortunately, to make queries like this you need to update your PostgreSQL.
If you have 9.3, then you need use json column type.
Here you can see some example. It helps me, earlier:
http://clarkdave.net/2013/06/what-can-you-do-with-postgresql-and-json/
Have a nice day.

For PostgreSQL 9.3 or higher, one possible solution could be using a cast to json:
SELECT * FROM playerbase_playerdata WHERE json_kvps->>'emailusername' = 'aaron#hotmail.com';
SELECT * FROM playerbase_playerdata WHERE CAST(json_kvps AS JSON)->>'emailusername' = 'aaron#hotmail.com';

In case of django models you can use JsonField.
https://pypi.python.org/pypi/jsonfield.
It works fine, but if you'll use PostgreSQL version less than 9.2, it'll create character column.

select [Required Fields] from [Table Name] WHERE [Column Name]::text = '{[Key]}' ::text

Related

How to display all columns and its data type in a table via SQL query

I am trying to print the column names from a table called 'meta' and I need also its data types.
I tried this query
SELECT meta FROM INFORMATION_SCHEMA.TABLES;
but it throws an error saying no information schema available. Could you please help me, I am a beginner in SQL.
Edit:
select tables.name from tables join schemas on
tables.schema_id=schemas.id where schemas.name=’sprl_db’ ;
This query gives me all the tables in database 'sprl_db'
You can use the monetdb catalog:
select c.name, c.type, c.type_digits, c.type_scale
from sys.columns c
inner join sys.tables t on t.id = c.table_id and t.name = 'meta';
as you are using monetDB you can get that by using sys.columns
sys.columns
it will return all information related to table columns
you can also check Schema, table and columns documentation for monetDB
in sql server we get that like this exec sp_columns TableName
If I understand correctly you need to see the columns and the types of a table you (or some other user) defined called meta?
There are at least two ways to do this:
First (as #GMB mentioned in their answer) you can query the SQL catalog: https://www.monetdb.org/Documentation/SQLcatalog/TablesColumns
SELECT * FROM sys.tables WHERE NAME='meta';
+------+------+-----------+-------+------+--------+---------------+--------+-----------+
| id | name | schema_id | query | type | system | commit_action | access | temporary |
+======+======+===========+=======+======+========+===============+========+===========+
| 9098 | meta | 2000 | null | 0 | false | 0 | 0 | 0 |
+------+------+-----------+-------+------+--------+---------------+--------+-----------+
1 tuple
So this gets all the relevant information about the table meta. We are mostly interested in the value of the column id because this uniquely identifies the table.
(Please note that this id will probably be different in your system)
After we have this information we can query the columns table with this table id:
SELECT * FROM sys.columns WHERE table_id=9098;
+------+------+------+-------------+------------+----------+---------+-------+--------+---------+
| id | name | type | type_digits | type_scale | table_id | default | null | number | storage |
+======+======+======+=============+============+==========+=========+=======+========+=========+
| 9096 | i | int | 32 | 0 | 9098 | null | true | 0 | null |
| 9097 | j | clob | 0 | 0 | 9098 | null | true | 1 | null |
+------+------+------+-------------+------------+----------+---------+-------+--------+---------+
2 tuples
Since you are only interested in the names and types of the columns, you can modify this query as follows:
SELECT name, type FROM sys.columns WHERE table_id=9098;
+------+------+
| name | type |
+======+======+
| i | int |
| j | clob |
+------+------+
2 tuples
You can combine the two queries above with a join:
SELECT col.name, col.type FROM sys.tables as tab JOIN sys.columns as col ON tab.id=col.table_id WHERE tab.name='meta';
+------+------+
| name | type |
+======+======+
| i | int |
| j | clob |
+------+------+
2 tuples
The second, and preferred way to get this information if you are using the mclient utility of MonetDB, is by using the describe meta-command of mclient. When used without arguments it presents a list of tables that have been defined in the current database and when it is given the name of the table it prints its SQL definition:
sql>\d
TABLE sys.data
TABLE sys.meta
sql>\d sys.meta
CREATE TABLE "sys"."meta" (
"i" INTEGER,
"j" CHARACTER LARGE OBJECT
);
You can use the \? meta-command to see a list of all meta-commands in mclient:
sql>\?
\? - show this message
\<file - read input from file
\>file - save response in file, or stdout if no file is given
\|cmd - pipe result to process, or stop when no command is given
\history - show the readline history
\help - synopsis of the SQL syntax
\D table - dumps the table, or the complete database if none given.
\d[Stvsfn]+ [obj] - list database objects, or describe if obj given
\A - enable auto commit
\a - disable auto commit
\e - echo the query in sql formatting mode
\t - set the timer {none,clock,performance} (none is default)
\f - format using renderer {csv,tab,raw,sql,xml,trash,rowcount,expanded,sam}
\w# - set maximal page width (-1=unlimited, 0=terminal width, >0=limit to num)
\r# - set maximum rows per page (-1=raw)
\L file - save client-server interaction
\X - trace mclient code
\q - terminate session and quit mclient
For MySQL:
SELECT column_name,
data_type
FROM information_schema.columns
WHERE table_schema = ’ yourdatabasename ’
AND table_name = ’ yourtablename ’;
Output:
+-------------+-----------+
| COLUMN_NAME | DATA_TYPE |
+-------------+-----------+
| Id | int |
| Address | varchar |
| Money | decimal |
+-------------+-----------+

Query to display records that were entered today in postgres (Epoch time)

I have a table with columns as:
Table "public.myapp_table1"
Column | Type | Modifiers | Storage | Stats target | Description
------------+------------------------+--------------------------------------------------------------+----------+--------------+-------------
id | integer | not null default nextval('myapp_database1_id_seq'::regclass) | plain | |
model_name | character varying(150) | not null | extended | |
device_id | character varying(150) | not null | extended | |
data | jsonb | not null | extended | |
Inside json field data, there is 'timestamp' where time is stored in epoch format (refer https://www.epochconverter.com/ )
I want to display all rows entered today.
I'm trying to query: (Bit newish in querying json data)
select distinct(device_id) from myapp_table1 where (data->'timestamp')> 1570077000;
where 1570077000 is today's epoch time starting 10:00 AM.
Error that I'm getting is:
ERROR: operator does not exist: jsonb > integer
LINE 1: ...ce_id) from myapp_table1 where (data->'timestamp')> 15700770...
^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Not sure how to manage that '>' sign. Didn't get the hold of docs yet.
How to tackle this?
You need to use ->> to get the JSON value as text, instead of ->, which returns a json object. Also, it is probably needed to cast the text value to an (big) integer.
Consider:
where (data->>'timestamp')::bigint > 1570077000
Reference: JSON Functions and Operators

What does this "t" do?

I'm having trouble understanding the following example from the PostgreSQL documentation:
-- set returning function WITH ORDINALITY
SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n);
ls | n
-----------------+----
pg_serial | 1
pg_twophase | 2
postmaster.opts | 3
pg_notify | 4
...
The things inside the parentheses of the t(...) become the column names, but what is the t itself? I'm asking here because the docs don't explain it, and a single-letter function is ungoogleable. In fact, the docs don't even explain what is supposed to come after AS; the only thing we get is this one example.
It seems I can replace t by any other identifier, and it still works.
The syntax you're looking for is:
function_call [WITH ORDINALITY] [[AS] table_alias [(column_alias [, ... ])]]
https://www.postgresql.org/docs/10/static/queries-table-expressions.html#QUERIES-TABLEFUNCTIONS
t is an arbitrary table alias; you can give it any valid name you want.
it's alias for a set, to be able to reference it in column list, eg:
SELECT t.*,pg_database .datname
FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n)
join pg_database on true where datname = 'postgres'
ls | n | datname
----------------------+----+----------
pg_dynshmem | 1 | postgres
postmaster.pid | 2 | postgres
PG_VERSION | 3 | postgres
base | 4 | postgres

Can't select an existing column in PostgreSQL

I'm new in SQL and I'm trying to select column Foto_municipis:
askdbase4=# select * from avatar_avatarx;
id | llista_municipis | Foto_municipis | primary | date_uploaded
----+------------------+-----------------+---------+------------------------
1 | Tore | tore.jpg | t | 2014-06-05 01:19:40+02
2 | Calldetenes | calldetenes.jpg | f | 2014-06-05 23:24:18+02
3 | Rupit i Pruit | baixa.jpeg | f | 2014-06-16 03:09:48+02
4 | Olost | olost.jpg | f | 2014-06-16 23:20:05+02
(4 rows)
for some reason I can select llista municipis successfully:
SELECT llista_municipis FROM avatar_avatarx;
but when I try to select Foto_municipis this is what I get:
askdbase4=# SELECT llista_municipis FROM avatar_avatarx;
ERROR: column "Foto_municipis" does not exist
LINE 1: select Foto_municipis from avatar_avatarx;
What am I doing wrong?
You probably created the column with a double-quoted identifier and this will work:
select "Foto_municipis"
from avatar_avatarx
That is almost always a bad idea as it will be forever necessary to reference it using double-quotes, unless it is an all lower case identifier in which case it can be referenced in lower case without double quotes.
If the column is created with an identifier without double quotes then it is possible to reference it in any case style like Foto_municipis or foto_Municipis regardless of the original identifier case style.

How to get numbers arranged right to left in sql server SELECT statements

When performing SELECT statements including number columns (prices, for example), the result always is left to right ordered, which reduces the readability. Therefore I'm searching a method to format the output of number columns right to left.
I already tried to use something like
SELECT ... SPACE(15-LEN(A.Nummer))+A.Nummer ...
FROM Artikel AS A ...
which gives close results, but depending on font not really. An alternative would be to replace 'SPACE()' with 'REPLICATE('_',...)', but I don't really like the underscores in output.
Beside that this formula will crash on numbers with more digits than 15, therefore I searched for a way finding the maximum length of entries to make it more save like
SELECT ... SPACE(MAX(A.Nummer)-LEN(A.Nummer))+A.Nummer ...
FROM Artikel AS A ...
but this does not work due to the aggregate character of the MAX-function.
So, what's the best way to achieve the right-justified order for the number-columns?
Thanks,
Rainer
To get you problem with the list box solved have a look at this link: http://www.lebans.com/List_Combo.htm
I strongly believe that this type of adjustment should be made in the UI layer and not mixed in with data retrieval.
But to answer your original question i have created a SQL Fiddle:
MS SQL Server 2008 Schema Setup:
CREATE TABLE dbo.some_numbers(n INT);
Create some example data:
INSERT INTO dbo.some_numbers
SELECT CHECKSUM(NEWID())
FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))X(x);
The following query is using the OVER() clause to specify that the MAX() is to be applied over all rows. The > and < that the result is wrapped in is just for illustration purposes and not required for the solution.
Query 1:
SELECT '>'+
SPACE(MAX(LEN(CAST(n AS VARCHAR(MAX))))OVER()-LEN(CAST(n AS VARCHAR(MAX))))+
CAST(n AS VARCHAR(MAX))+
'<'
FROM dbo.some_numbers SN;
Results:
| COLUMN_0 |
|---------------|
| >-1486993739< |
| > 1620287540< |
| >-1451542215< |
| >-1257364471< |
| > -819471559< |
| >-1364318127< |
| >-1190313739< |
| > 1682890896< |
| >-1050938840< |
| > 484064148< |
This query does a straight case to show the difference:
Query 2:
SELECT '>'+CAST(n AS VARCHAR(MAX))+'<'
FROM dbo.some_numbers SN;
Results:
| COLUMN_0 |
|---------------|
| >-1486993739< |
| >1620287540< |
| >-1451542215< |
| >-1257364471< |
| >-819471559< |
| >-1364318127< |
| >-1190313739< |
| >1682890896< |
| >-1050938840< |
| >484064148< |
With this query you still need to change the display font to a monospaced font like COURIER NEW. Otherwise, as you have noticed, the result is still misaligned.