Cannot unnest json in postgres - json

create table json_example as
select '[{"a":1,"b":"foo"},{"a":"2","c":"bar"}]'::jsonb as value
select * from json_example
the following is working fine:
select * from json_array_elements('[{"a":1,"b":"foo"},{"a":"2","c":"bar"}]')
And i want to do the same, only difference that json is coming from a table. how to do the same using json_example table value field?

cross join json_array_elements with the table
select j.* from json_example cross join
json_array_elements(value) as j
DEMO

Related

Save the intermediate result of SQL query

I am wondering if there is any way to save the intermediate result or tables in SQL. For example assume you have two different SQL statements that in the first statement you join two tables, then you want to see how many rows the resulting table has. I know there are many ways to do this but I am interested in seeing how this can be done sequentially. Consider the following example:
select * from order_table left join customer_table on order_table.id = customer_table.id
Then I want to see count of number of rows (as an easy example)
select count(*) from table
But I do not know what this table should be. How may I save the result of above query in some logical table or how to refer to what was created before in SQL.
You can use WITH like below:
WITH resultTable as ( select * from order_table left join customer_table on order_table.id = customer_table.id )
select count(*) from resultTable
For this particular example you can simply wrap the original query in a sub-query:
select count(*)
from (
select *
from order_table
left join customer_table on order_table.id = customer_table.id
) as x
If you want to store the result in a physical table (temporary or permanent) then the procedure varies for each rdbms. In SQL Server for example you would use SELECT INTO:
select *
into #temp_table
from order_table
left join customer_table on order_table.id = customer_table.id
you can also use CTE. for your question it will be:
;
with table1 as (
select * from order_table
left join customer_table on order_table.id = customer_table.id
)
select count(*) from table1
GO

How To Create Table Easily From A Join Result on Tables with Same Column/Field Names

I am trying to do a join on 2 tables that have the same schema:
SELECT * FROM `tl1` INNER JOIN `tl2` ON tl1.urlid = tl2.urlid
This works ok, until I decide to modify the query to save it:
CREATE TABLE `tableName` SELECT * FROM `tl1` INNER JOIN `tl2` ON tl1.urlid = tl2.urlid
This gives an error saying that there are duplicate columns.
I have a primary key in both tables.
I found a solution by aliasing each column from each table like this:
CREATE TABLE `tableName` SELECT tl1.id AS L_id1, tl1.filepath AS L_filepath1, tl1.urlid AS L_urlid1, tl1.fieldname AS L_fieldname1, tl1.fieldvalue AS L_fieldvalue1, tl2.id AS L_id2, tl2.filepath AS L_filepath2, tl2.urlid AS L_urlid2, tl2.fieldname AS L_fieldname2, tl2.fieldvalue AS L_fieldvalue2 FROM `tl1` INNER JOIN `tl2` ON tl1.urlid = tl2.urlid
However, this is tedious. What if there were 100+ columns in each table? Is there a way to make this work without having to manually aliasing each column name? I am looking for something that will make MySQL create a table with column names of the format "X.Y" where X is the original table name and Y is the original field name, but any other solutions would do as well.
P.S.: If it's not clear, when I used "*", I needed columns from both tables, not just one. They are two different tables with different data but with the same column names. (I can't change the names, by the way.)
You can do something like this (I don't understand why you want to create a 3rd table where it seems you already have twice the same data):
CREATE TABLE `tableName` SELECT tl1.* FROM `tl1` INNER JOIN `tl2` ON tl1.urlid = tl2.urlid
First, using mysql workbench. you need to create the following view, by clicking on the desired schema, then right-clicking on view.
It should look something like this:
CREATE VIEW `schema`.`someView` (
SELECT t1.*
FROM `tl1` as t1
JOIN `tl2` as t2
ON (t1.urlid = t2.urlid)
)
Now save it, then reopen it in the "views" tab and you should see this:
CREATE VIEW `schema`.`someView` (
SELECT
t1.col1,
t1.col2,
t1.col3,
...
FROM `tl1` as t1
JOIN `tl2` as t2
ON (t1.urlid = t2.urlid)
)
Now you can an alias to the duplicate columns, then add a t2.* to add the rest of the columns
CREATE VIEW `schema`.`someView` (
SELECT
t1.id as tl1_id,
...
t2.*
FROM `tl1` as t1
JOIN `tl2` as t2
ON (t1.urlid = t2.urlid)
)
This is the fastest way I know to do this. Hope it helps.

two tables query with same primary key

I have two tables with same primary key name "codigo",
I try to make a mysql query to combine both results on new one table.
SELECT * FROM recuperacion.inventario, recuperacion.Salidas where codigo='5ae2399f4fbd3';
this query is not work.
You need to join the tables.
SELECT *
FROM recuperacion.inventario
INNER JOIN recuperacion.Salidas USING (codigo)
WHERE codigo='5ae2399f4fbd3';
The USING clause can be used when the joining relationship is the same column name(s) in both tables. This then allows you to refer to that column without qualifying it with a table prefix.
SELECT t1.*, t2.*
-- INTO NewTableName
FROM recuperacion.inventario t1
INNER JOIN recuperacion.Salidas t2
ON t1.codigo = t2.codigo
WHERE t1.codigo='5ae2399f4fbd3'
NOTE: this will get you all columns from both tables. If you only want specific columns you need to edit the select list. Just be sure to use the aliases.
you have to use join
SELECT *
FROM recuperacion.inventario tab1
INNER JOIN recuperacion.Salidas tab2
on tab1.codigo = tab2.codigo
where tab1.codigo='5ae2399f4fbd3'
Use a JOIN syntax for the query:
SELECT *
FROM recuperacion.inventario a JOIN recuperacion.Salidas b
ON a.codigo = b.codigo
WHERE a.codigo='5ae2399f4fbd3';

Selecting distinct values from joined results in Mysql

I am trying to access complete data from two tables in mysql and then find distinct values of a column from the resulting set. tried doing with nested query as follows :-
Select distinct s.BlockName
from (SELECT *
FROM constucted
LEFT JOIN required ON constucted.BlockName = required.BlockName
UNION
SELECT *
FROM constucted
RIGHT JOIN required ON constucted.BlockName = required.BlockName
) s
As mentioned in Stackoverflow Reference
and also tried using the with keyword as follows :-
WITH CTE
AS
(
SELECT *
FROM constucted
LEFT JOIN required ON constucted.BlockName = required.BlockName
UNION
SELECT *
FROM constucted
RIGHT JOIN required ON constucted.BlockName = required.BlockName
)
SELECT DISTINCT BlockName
FROM CTE
But unable to find the distinct value for the column BlockName unable to prepare a query for the same.
Your query would seem to be more simply written as:
select BlockName
from constructed
union -- intentional to remove duplicates
select BlockName
from required;

Find values missing in a column from a set (mysql)

I am using mysql.
I have a table that has a column id.
Let us say I have an input set of ids. I want to know which all ids are missing in the table.
If the set is "ida", "idb", "idc" and the table only contains "idb", then the returned value should be "ida", "idc".
Is this possible with a single sql query? If not, what is the most efficient way to execute this.
Note that I am not allowed to use stored procedure.
MySQL will only return rows that exist. To return missing rows you must have two tables.
The first table can be temporary (session/connection specific) so that multiple instances can run simultaneously.
create temporary table tmpMustExist (text id);
insert into tmpMustExist select "ida";
insert into tmpMustExist select "idb";
-- etc
select a.id from tmpMustExist as a
left join table b on b.id=a.id
where b.id is null; -- returns results from a table that are missing from b table.
Is this possible with a single sql query?
Well, yes it is. Let me work my way to that, first with a union all to combine the select statements.
create temporary table tmpMustExist (text id);
insert into tmpMustExist select "ida" union all select "idb" union all select "etc...";
select a.id from tmpMustExist as a left join table as b on b.id=a.id where b.id is null;
Note that I use union all which is a bit faster than union because it skips over deduplication.
You can use create table...select. I do this frequently and really like it. (It is a great way to copy a table as well, but it will drop indexes.)
create temporary table tmpMustExist as select "ida" union all select "idb" union all select "etc...";
select a.id from tmpMustExist as a left join table as b on b.id=a.id where b.id is null;
And finally you can use what's called a "derived" table to bring the whole thing into a single, portable select statement.
select a.id from (select "ida" union all select "idb" union all select "etc...") as a left join table as b on b.id=a.id where b.id is null;
Note: the as keyword is optional, but clarifies what I'm doing with a and b. I'm simply creating short names to be used in the join and select field lists
There's a trick. You can either create a table with expected values or you can use union of multiple select for each value.
Then you need to find all the values that are in the etalon, but not in the tested table.
CREATE TABLE IF NOT EXISTS `single` (
`id` varchar(10) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `single` (`id`) VALUES
('idb');
SELECT a.id FROM (
SELECT 'ida' as id
UNION
SELECT 'idb' as id
UNION
SELECT 'idc' AS id
) a WHERE a.id NOT IN (SELECT id FROM single)
//you can pass each set string to query
//pro-grammatically you can put quoted string
//columns must be utf8 collation
select * from
(SELECT 'ida' as col
union
SELECT 'idb' as col
union
SELECT 'idc' as col ) as setresult where col not in (SELECT value FROM `tbl`)