flat file sql needed (old data concepts ) - sql

I need to get that email address. The definition of this Physical File is: I have a crystal report that is going to have the sales rep id name (DMARANO1). I need to get the email address of the rep so the report can send to him/her only on correct rep data.
1-4 CAT
5-20 REF FILE SELECTION
21-22 RFSQ2
23-62 RDATA
63-63 FILLER
64-64 ACTIVITY CODE
As I see it, the 0025 has the sales rep name and code (code = DM1), then the 8757 has that code DM1 and the email.
I need to read the 0025, get the code, on the '01' record, then read the 8757
I would have the DMARANO1 to match on (the 0075 record.)
this is not ideal way but we are using a very old Iseries code here.
0025DM1 01DEMI MARANO 0000000 +
0025DM1 02000000 +
0075DMARANO1 01 +
0075DMARANO1 02 00 +
0075DMARANO1 0311OACI 11 1 +
0075DMARANO1 05 0 +
0075DOLDHOFF 01 +
0075DOLDHOFF 02 00 +
0075DOLDHOFF 0311OACI 11 1 +
0075DOLDHOFF 05 0 +
8511DS55 010030210210004000000002500000030000000000 +
8511DS55 02000000023400006250001750PLSSDM55 GOLD +
8506DMARANO1 01CUS1 +
0069DS55 01ENG-1.75"X.625" GOLD FLEXI 7000 +
7012DMARANO1 01 +
8757DM1 01DMARANO#TESTAWARDS.COM +
8757DM1 02914-347-7566452DEMI MORANO
8511GNPY 010110180180004000000002500000110000000000

Assuming the physical file is named FILE, it contains a single 64 character field named FILE, and the records can be joined on REF_FILE_SELECTION and RFSQ2 the following SQL should get you started:
WITH CTE AS (
SELECT
SUBSTR(FILE, 1, 4) CAT,
SUBSTR(FILE, 5, 15) REF_FILE_SELECTION,
SUBSTR(FILE, 21, 2) RFSQ2,
SUBSTR(FILE, 23, 40) RDATA,
SUBSTR(FILE, 63, 1) FILLER,
SUBSTR(FILE, 64, 1) ACTIVITY_CODE
FROM FILE)
SELECT A.REF_FILE_SELECTION, B.RDATA
FROM CTE A
JOIN CTE B ON A.REF_FILE_SELECTION = B.REF_FILE_SELECTION AND A.RFSQ2 = B.RFSQ2
WHERE A.CAT='0025' AND A.RFSQ2='01' AND B.CAT='8757'

Related

extract data from clob column in oracle

I am having data in clob column as below:
:1A:CAD22021828,17
:1B:RECEIVE GENERAL IND
11 BEGUM ST 3-15A2
VILL AP IND 313 416
:1C:/000061071257 CC
RECEIVER GENERAL FOR IND
C/O PNBB MAIN BRANCH
11 BEGUM ST 3-15A2
AA HYD APIND
Now my requirement is to load this into 3 separate columns in target table as below:
1A - CAD22021828,17
1B - RECEIVE GENERAL IND
11 BEGUM ST 3-15A2
VILL AP IND 313 416
1C - /000061071257 CC
RECEIVER GENERAL FOR IND
C/O PNBB MAIN BRANCH
11 BEGUM ST 3-15A2
AA HYD APIND
can someone suggest how I can do this.
This is oracle 11.2
I have tried below code ;
SELECT
REGEXP_SUBSTR(mc_clob,':1A:([[:alnum:]]+\S+)') AS code1A,
REGEXP_SUBSTR(mc_clob,':1B:([[:alnum:]]+\s+)') AS code1B,
REGEXP_SUBSTR(mc_clob,':1C:([[:alnum:]]+\s+)') AS code1c
FROM tableA;
Here is one way to do this using REGEXP_SUBSTR with capture groups:
SELECT
REGEXP_SUBSTR(mc_clob, ':1A:(.*):1B:', 1, 1, 'n', 1) AS code1A,
REGEXP_SUBSTR(mc_clob,':1B:(.*):1C:', 1, 1, 'n', 1) AS code1B,
REGEXP_SUBSTR(mc_clob,':1C:(.*)', 1, 1, 'n', 1) AS code1c
FROM tableA;
Demo
To understand how this works, take the first call to REGEXP_SUBSTR:
REGEXP_SUBSTR(mc_clob, ':1A:(.*):1B:', 1, 1, 'n', 1)
This says to match :1A:(.*):1B:, capturing all content between the :1A: and :1B: markers. The fifth parameter is n, which tells Oracle to let dot match across newlines. That is, (.*) will capture all content between the two markers, including across lines. The sixth parameter is 1, which means that the return value will be the first (and only) capture group. Similar logic applies to the second and third call to REGEXP_SUBSTR.

Parse nested JSON in SQL Server

I have stored data in sql server as Json format, which as give below. I would like to retrieve it as normal string value. I have tried JSON_VALUE but json may or may not have more than one child, so it should retrieve all the values.
Input
TableA
ID Education
-------------------------------------------------------------------------------------
1 {"Education": {"Record":[{"SLSubject":"MICRO ECONOMICS","Score":"77","Grade":"A"}]}}
2 {"Education": {"Record":[{"SLSubject":"Math","Score":"89","Grade":"A"},{"SLSubject":"eng","Score":"88","Grade":"B"},{"SLSubject":"tam","Score":"33","Grade":"C"}]}}
3 {"Education":{"Record":[{"SLSubject":"subject 1","Score":"87","Grade":"A"},{"SLSubject":"subject 2","Score":"67","Grade":"B"},{"SLSubject":"subject 3","Score":"45","Grade":"C"},{"SLSubject":"subject 4","Score":"87","Grade":"D"}]}}
Expected Output
ID Education
-------------------------------------------------------------------------------------
1 MICRO ECONOMICS - 77 - A
2 Math - 88 - B \n end - 88 - B \n Tam - 33 - C
3 subject 1 - 87- A \n subject 2 - 67- B \n subject 3 - 45- C \n subject 1 - 87- D \n
Query (which is working for one child)
SELECT ID, JSON_VALUE(Education,'$.Education.Record[0].SLSubject')
FROM TableA
Actual Result
ID Education
-------------------------------------------------------------------------------------
1 MICRO ECONOMICS - 77 - A
2 Math - 88 - B
3 subject 1 - 87- A
Sample JSON:
{"Education":{"Record":[{"SLSubject":"subject 1","Score":"87","Grade":"A"},{"SLSubject":"subject 2","Score":"67","Grade":"B"},{"SLSubject":"subject 3","Score":"45","Grade":"C"},{"SLSubject":"subject 4","Score":"87","Grade":"D"}]}}
You need to use OPENJSON and treat your data as a dataset, JSON_VALUE is for returning a scalar value. This'll likely be what you really want:
SELECT YT.ID,
OJ.SLSubject,
OJ.Score,
OJ.Grade
FROM (VALUES(1,N'[{"SLSubject":"MICRO ECONOMICS","Score":"77","Grade":"A"}]'),
(2,N'[{"SLSubject":"Math","Score":"89","Grade":"A"},{"SLSubject":"eng","Score":"88","Grade":"B"},{"SLSubject":"tam","Score":"33","Grade":"C"}]'),
(3,N'[{"SLSubject":"subject 1","Score":"87","Grade":"A"},{"SLSubject":"subject 2","Score":"67","Grade":"B"},{"SLSubject":"subject 3","Score":"45","Grade":"C"},{"SLSubject":"subject 4","Score":"87","Grade":"D"}]'))YT(ID,Education)
CROSS APPLY OPENJSON(YT.Education)
WITH (SLSubject varchar(20),
Score int,
Grade char(1)) OJ;
Seems the OP wants this?
SELECT YT.ID,
STRING_AGG(CONCAT(OJ.SLSubject, ' - ', OJ.Score, ' - ', OJ.Grade),' \n ') WITHIN GROUP (ORDER BY OJ.SLSubject) AS Education
FROM (VALUES(1,N'[{"SLSubject":"MICRO ECONOMICS","Score":"77","Grade":"A"}]'),
(2,N'[{"SLSubject":"Math","Score":"89","Grade":"A"},{"SLSubject":"eng","Score":"88","Grade":"B"},{"SLSubject":"tam","Score":"33","Grade":"C"}]'),
(3,N'[{"SLSubject":"subject 1","Score":"87","Grade":"A"},{"SLSubject":"subject 2","Score":"67","Grade":"B"},{"SLSubject":"subject 3","Score":"45","Grade":"C"},{"SLSubject":"subject 4","Score":"87","Grade":"D"}]'))YT(ID,Education)
CROSS APPLY OPENJSON(YT.Education)
WITH (SLSubject varchar(20),
Score int,
Grade char(1)) OJ
GROUP BY YT.ID;
DB<>Fiddle

Can't Import Data in Condition of Date with read.csv.sql

Environment: R
Goal: import all data from a csv where Start Date is before 10/1/2013
Data Structure:
Trip ID Duration Start Date Start Station
4576 63 8/29/2013 14:13 South Van Ness at Market
4607 70 8/29/2013 14:42 San Jose City Hall
4130 71 8/29/2013 10:16 Mountain View City Hall
4251 77 8/29/2013 11:29 San Jose City Hall
Code:
library(sqldf)
tripData <- read.csv.sql("201402_trip_data.csv", sql = "select * from file where 'Start Date' <= '10/1/2013'",header = TRUE, eol = "\n")
Question:
There's no warnings in R, but the result shows that only 11 variables name were imported, but no observation in the tripData.
Your query has a problem:
select * from file where 'Start Date' <= '10/1/2013'
This is telling SQL to lexicographically compare the string 'Start Date' to '10/1/2013'. I believe that this will never be true, because the letter S compares after the number 1. You need to use backticks, not quotes, around the column name. This is the query which you intended to run:
select * from file where `Start Date` <= '10/1/2013'
> tripData <- read.csv.sql("201402_trip_data.csv", sql = "select * from file where `Start Date` <= '10/1/2013'",header = TRUE, eol = "\n")

SQL: Dynamically Transposing Column as Row in Chartio

I would love to have your help transposing this table's column into a row. I am trying to have the Project Names (column 1) each becoming their own column header with the MUVs value entered as the column value.
I have read through 20+ threads on this topic, but they are using different SQL packages and code that I am unable to use.
The ideal solution would modify this query to create the desired query output:
Current Query:
SELECT
cust_gae_account.project_name as "Project Name",
cust_be_project_usage.unique_visitor_count as "MUVs",
cust_be_project_usage.billing_period_start as "Month"
FROM
cust_be_project_usage
INNER JOIN
cust_gae_account
ON cust_gae_account.account_id = cust_be_project_usage.project_id
WHERE
cust_be_project_usage.admin_account_id = {ACCOUNT_ID}
Current Query Output:
Project Name | MUVs | Month
-----------------------------------------------------
ProjectAAAAAZ | 68000 | Jun 01, 2016
DynamicName | 3200 | Jun 01, 2016
ProjectAAAAAZ | 21000 | May 01, 2016
DynamicName | 4500 | May 01, 2016
CustomProject | 117000 | Jun 01, 2016
CustomProject | 118400 | May 01, 2016
Desired Query Output:
Project Name | CustomProject | ProjectAAAAAZ | DynamicName
-------------------------------------------------------------------
Jun 01, 2016 | 117000 | 68000 | 3200
May 01, 2016 | 118400 | 21000 | 4500
Notes:
We are using PostgreSQL via Chartio, we can only use base SQL
We cannot use custom functions sadly
Names and number of projects is dynamic, varies from 1 to 20
MUVs are always numeric, there are no duplicates
You can use crosstab https://www.postgresql.org/docs/9.1/static/tablefunc.html , but it will only work with a static list of columns. So you need a dynamic query. You need to define that query, and execute it.
EXECUTE ('SELECT * FROM crosstab(
\'SELECT
cust_be_project_usage.billing_period_start as "Month",
cust_gae_account.project_name as "Project Name",
cust_be_project_usage.unique_visitor_count as "MUVs"
FROM
cust_be_project_usage
INNER JOIN
cust_gae_account
ON cust_gae_account.account_id = cust_be_project_usage.project_id
WHERE
cust_be_project_usage.admin_account_id = {ACCOUNT_ID}\',
\'SELECT
cust_gae_account.project_name as "Project Name"
FROM
cust_be_project_usage
INNER JOIN
cust_gae_account
ON cust_gae_account.account_id = cust_be_project_usage.project_id
WHERE
cust_be_project_usage.admin_account_id = {ACCOUNT_ID}\')
AS ( "Project Name" date, ' ||
(SELECT
string_agg(cust_gae_account.project_name, ' int,')
FROM
cust_be_project_usage
INNER JOIN
cust_gae_account
ON cust_gae_account.account_id = cust_be_project_usage.project_id
WHERE
cust_be_project_usage.admin_account_id = {ACCOUNT_ID}) || ' int'
|| ' )')
I am not able to test it though. It SHOULD work, but my suspicions are that it might not, in these situations:
Concatenating to a scalar formed by a query (might need to use a variable for that one)
I might have mixed up a column somewhere
Not sure how you pass the {ACCOUNT_ID} parameter so you might need to change that too

Finding data from specific value in an array in SQL

Morning All,
I have an Allowed systems field in my record that can contain an array such as: 22, 18, 21
What I want to do is if system 18 is accessing the database and is pulling all the records that are allowed for system 18, how can I write that in sql.
+----------+----------------+------------+
| AdvertID | AllowedSystems | AdvertName |
+----------+----------------+------------+
| 47 | 22, 18, 21, 3 | GeorgesAd |
+----------+----------------+------------+
| 49 | 2, 7, 9, 6 | StevesAd |
+----------+----------------+------------+
| 47 | 18, 12, 32, 8 | PetesAd |
+----------+----------------+------------+
Any assistance would be greatly appreciated.
Have a great day..!
Paul Jacobs
This will test for the best performing cases first, in the hopes of getting some performance out of what is destined to be an inefficient query due to the denormalized structure.
The first two WHERE clauses can take advantage of an index on AllowedSystems, although this may be helpful in only a small number of cases, depending on what your data is like.
select AdvertID, AdvertName
from MyTable
where AllowedSystems = '18'
or AllowedSystems like '18,%'
or AllowedSystems like '%, 18'
or AllowedSystems like '%, 18,%'
Note: I add a space to the beginning of the searched column and a comma to the end to account for the cases where 18 is the first or last entry in the list. I then search for ' 18,' within the string.
select *
from YourTable
where charindex(' 18,', ' ' + AllowedSystems + ',') <> 0
First, this is a bad idea for a data structure. You should probably normalize by adding an AllowedSystems table with a record for each pair of system and Advert.
Second, you would want to use this:
SELECT AdvertID, AdvertName
FROM MyTable
WHERE AllowedSystems LIKE '%18%'
You're going to have issues when you get over 100 systems, since there is no way to tell if the hit is for 18 or 118 or 181.
EDIT:
Or you can use RedFilter's multiple WHERE conditions to avoid the above issue with 18, 118, or 181.
The poor performance way would be:
SELECT AdvertID, AdvertName
FROM YourTable
WHERE ', ' + AllowSystems + ', ' LIKE '%, 18, %'
However, ideally you should have an extra table that has a compound key:
Table: AdvertAllowedSystem
AdvertID
SystemID
so that you can do a more performant, SARGable query:
SELECT a.AdvertID, a.AdvertName
FROM AdvertAllowedSystem s
INNER JOIN Advert a ON s.AdvertId = a.AdvertId
WHERE s.SystemId = 18
In addition if you have possibility to changed the design of create a materialized view, for this you may use hierarchyid Data Type or Rank and Unrank