select column of JSON arrays and show elements as new columns - arrays

I have a Postgres DB with a column that has a JSON array for the value in each row.
Example:
id | json_data
1 | [{"sub_id":"a1", "flag":"true", "type":"something"}, {"sub_id":"a2", "flag":"true", "type":"something"}]
2 | [{"sub_id":"b1", "flag":"false", "type":"something"}, {"sub_id":"b2", "flag":"false", "type":"something"}]
3 | [{"sub_id":"c1", "flag":"true", "type":"something"}]
I want to be able create a new view so that I can interact with data structured like this:
id | sub_id | flag | type
1 | a1 | true | something
1 | a2 | true | something
2 | b1 | false | something
2 | b2 | false | something
3 | c1 | true | something
Perhaps there is something I am not understanding from the Postgres documentation. It seems like I need to to leverage json_array_elements but all of the documentation and related examples I see show the JSON being passed as a string to this function.
How to I do I use this for each row of a given column?

You need to unnest using jsonb_array_elements, then you can access each key:
select t.id,
j.e ->> 'sub_id' as sub_id,
j.e ->> 'flag' as flag,
j.e ->> 'type' as type
from the_table t
cross join jsonb_array_elements(t.json_data::jsonb) as j(e)
order by t.id;
This assumes your column is defined as jsonb (which it should be). If it's just json you need to use json_array_elements()

Related

Replacing placeholder with another table's data (without knowing in advance the substitutions)

I need to replace placeholders in a text, reading from a query matched to that specific message.
Table Template_Messages
| ID | String | Query
| PICKUP_MSG|Your {vehicle_name} will be ready for pick-up on {pickup_date}|SELECT * FROM vehicles WHERE ID = ?
If I take the query I find in the 'Query' column, I will find the following table:
Table Vehicles
| ID | vehicle_name | plate | pickup_date | ... |
| P981| BMW X5 | AA014CC| 2022-09-20 | ... |
| Z323| Ford Focus | HH000JJ| 2022-10-21 | ... |
Then with the following query:
SELECT * FROM vehicles WHERE ID = 'Z323'
By making the appropriate substitutions I should obtain this output:
Your Ford Focus will be ready for pick-up on 2022-10-21
How can I achieve this?
And since the 'query' column of the first table does not only refer to the 'vehicles' table, can it work dynamically on any placeholder/query?

How to get data into a CTE and do an update

Using MS SQL Server, I want to:
Get data from my application
Perform preprocessing
Update a table
Steps 1 and 3 are giving me problems.
Simplifying the problem to its essence, my existing data looks like:
+--------+-------+
| Item | Usage |
+--------+-------+
| Part A | 10 |
| Part B | 15 |
| Part C | 8 |
+--------+-------+
and an example of the source data is:
+--------+
| Item |
+--------+
| Part A |
| Part B |
| Part B |
| Part B |
| Part A |
| Part A |
+--------+
My over all plan is to import the data into a CTE, do the preprocessing, then do an update.
Regarding getting the data, since "INTO" is not allowed in a CTE, how can I get the source data into the CTE. Or some other approach not using a CTE better?
Preprocessing is straightforward. Here is my SQL:
WITH MyData (Item, NewUsage)
AS
(
<Somehow get the data>
SELECT Item, Count(*) as NewUsage
FROM Items
GROUP BY Item
)
UPDATE Items
SET Usage = Usage + b.NewUsage
FROM Items as a JOIN MyData as b ON a.Item = b.Item;
The update is updating all the rows in Items by 1 instead of using the NewUsage column.
How do I get my data (into the CTE?) and how to write the SQL so it works properly?

SSRS How to Concatenate Multiple Rows with Dynamic Columns

Right now I have dynamic columns based off of a query, and then I have data attached to those columns that I want to populate in rows. They associate just fine, but the problem is that the rows hold whatever place they were in, instead of ascending to the top again, like so:
|column|column2|column3|
| row1 | | |
| | row2 | |
| | | row3 |
And the goal is:
|column|column2|column3|
| row1 | row2 | row3 |
| | | |
| | | |
I know that I could do this in the query, combining the headers with a dynamic query, but is there any SSRS magic that can achieve this without that?
EDIT 1
I am using a matrix, sorry about not specifying, I heard that the only way to do dynamic columns are matrices, so I thought it was implied.
EDIT 2
The rows come in like
Wanted_Column | Wanted Row
Column | data
Column2 | data
Column | data
and I want it so that the table will look like
|column|column2|
| data | data |
| data | |
| | |
for any number of columns/rows
I'm assuming you are using a matrix to do this. It's not clear from your question... Anyway, you'll need to add row grouping. If you don't have data that can be grouped by an actual column value then set the group expression to 1 and that should do it.
If this is not correct then please show you data as it comes from the dataset and the expected output.

Create/Update table in MS Access dynamically

EDIT:
Here's what I have: An Access database made up of 3 tables linked from SQL server. I need to create a new table in this database by querying the 3 source tables. Here are examples of the 3 tables I'm using:
PlanTable1
+------+------+------+------+---------+---------+
| Key1 | Key2 | Key3 | Key4 | PName | MainKey |
+------+------+------+------+---------+---------+
| 53 | 1 | 5 | -1 | Bikes | 536681 |
| 53 | 99 | -1 | -1 | Drinks | 536682 |
| 53 | 66 | 68 | -1 | Balls | 536683 |
+------+------+------+------+---------+---------+
SpTable
+----+---------+---------+
| ID | MainKey | SpName |
+----+---------+---------+
| 10 | 536681 | Wing1 |
| 11 | 536682 | Wing2 |
| 12 | 536683 | Wing3 |
+----+---------+---------+
LocTable
+-------+-------------+--------------+
| LocID | CenterState | CenterCity |
+--- ---+-------------+--------------+
| 10 | IN | Indianapolis |
| 11 | OH | Columbus |
| 12 | IL | Chicago |
+-------+-------------+--------------+
You can see the relationships between the tables. The NewMasterTable I need to create based off of these will look something like this:
NewMasterTable
+-------+--------+-------------+------+--------------+-------+-------+-------+
| LocID | PName | CenterState | Key4 | CenterCity | Wing1 | Wing2 | Wing3 |
+-------+--------+-------------+------+--------------+-------+-------+-------+
| 10 | Bikes | IN | -1 | Indianapolis | 1 | 0 | 0 |
| 11 | Drinks | OH | -1 | Columbus | 0 | 1 | 0 |
| 12 | Balls | IL | -1 | Chicago | 0 | 0 | 1 |
+-------+--------+-------------+------+--------------+-------+-------+-------+
The hard part for me is making this new table dynamic. In the future, rows may be added to the source tables. I need my NewMasterTable to reflect any changes/additions to the source. How do I go about building the NewMasterTable as described? Does this make any sort of sense?
Since an Access table is a necessary requirement, then probably the only way to go about it is to create a set of Update and Insert queries that are executed periodically. There is no built-in "dynamic" feature of Access that will monitor and update the table.
First, create the table. You could either 1) do this manually from scratch by defining the columns and constraints yourself, or 2) create a make-table query (i.e. SELECT... INTO) that generates most of the schema, then add any additional columns, edit necessary details and add appropriate indexes.
Define and save Update and Insert (and optional Delete) queries to keep the table synced. I'm not sharing actual code here, because that goes beyond your primary issue I think and requires specifics that you need to define. Due to some ambiguity with your key values (the field names and sample data still are not sufficient to reveal precise relationships and constraints), it is likely that you'll need multiple Update statements.
In particular, the "Wing" columns will likely require a transform statement.
You may not be able to update all columns appropriately using a single query. I recommend not trying to force such an "artificial" requirement. Multiple queries can actually be easier to understand and maintain.
In the event that you experience "query is not updateable" errors, you may need to define other "temporary" tables with appropriate indexes, into which you do initial inserts from the linked tables, then subsequent queries to update your master table from those.
Finally, and I think this is the key to solving your problem, you need to define some Access form (or other code) that periodically runs your set of "sync" queries. Access forms have a [Timer Interval] property and corresponding Timer event that fires periodically. Add VBA code in the Form_Timer sub that runs all your queries. I would suggest "wrapping" such VBA in a transaction and adding appropriate error handling and error logging, etc.

Django QuerySet - Multiple Order By when there is a single field per record

I am accessing an API where the number of fields can change at any time, but I must store and display the data as a table. Therefore, each record from the API is stored as a single record per field. My problem is that I am having trouble working out how I would order by multiple columns at a time. Putting all of the data into a 2D array (list of lists) before sorting is not a viable option as the number of records could be too large to feasibly hold in memory.
I've put together a simple example to explain. If anyone has an idea on how to overcome the problem, or how I could redesign my approach, I'd be very grateful.
| record_id | field | data |
| 1 | x | 2 |
| 1 | y | 1 |
| 1 | z | 3 |
| 2 | x | 30 |
| 2 | y | 42 |
| 2 | z | 7 |
| 3 | x | 53 |
| 3 | y | 2 |
| 3 | z | 7 |
If ordering by fields 'z' then 'x' (both ascending), the record order would be 1,2,3
If ordering by fields 'z' then 'y' (both ascending), the record order would be 1,3,2
I am using models in django to store and I am using QuerySets to retrieve the data. I don't have any control over the API or database from which I am originally accessing the data.
After a fair amount of research I realised I was going about this all wrong - I am now using an hstore field in postgres and django-hstore to utilise it, for a schema-less approach. I now have a single row per original record and I can order_by after casting the required field in an 'extra' method.

Resources