SQL server: retrieve grouped data from a table - sql

Write SQL query based on info below Table TRACK_BY_WCN
CREATE TABLE CONTRACTOPS.TRACK_BY_WCN(
CLAIM_TYPE CHAR(1 BYTE)
,LOBID CHAR(3 BYTE)
,WCN VARCHAR2(10 BYTE)
,RECEIVED_DATE DATE
,FOUND_DATE DATE
,CLAIM_NUMBER VARCHAR2(10 BYTE) DEFAULT NULL
,HOLD_FLAG CHAR(1 BYTE) DEFAULT NULL
,LOCK_FLAG VARCHAR2(3 BYTE) DEFAULT NULL
,BILLED NUMBER(16,2))
There are data in first 3 columns, CLAIM_TYPE, LOBID, WCN, and there is program doing match by WCN. When found, the program will update all other fields. Please use one SQL to get count on how many WCN and how many matched claims, by claim type.

It's hard to tell what you are asking exactly. This might be what you want:
Count rows per WCN:
SELECT WCN, count(*) AS row_count
FROM CONTRACTOPS.TRACK_BY_WCN
GROUP BY WCN;
Count rows per CLAIM_TYPE
SELECT CLAIM_TYPE, count(*) AS row_count
FROM CONTRACTOPS.TRACK_BY_WCN
GROUP BY CLAIM_TYPE;
Count claims per WCN and CLAIM_TYPE
SELECT WCN, CLAIM_TYPE, count(*) AS row_count
FROM CONTRACTOPS.TRACK_BY_WCN
GROUP BY WCN, CLAIM_TYPE;

Related

Range partition on CHAR/VARCHAR2 data type for every month

We have a table where we are trying to create a RANGE partition on CHAR data type for each month as mentioned below. But we are getting errors.The ACC_DATE value will be like '202010'. Can this be done in ORACLE? because the same can be done in DB2. But we have to implement it in ORACLE.
Error we are getting:
ORA-14751: Invalid data type for partitioning column of an interval partitioned table
CREATE TABLE T_ACCOUNT_PARTITION
(
V_ACCOUNT_NUM VARCHAR2(100 CHAR),
V_ACCOUNT_NAME VARCHAR2(200 CHAR),
ACC_DATE CHAR(6)
)
PARTITION BY RANGE (ACC_DATE) INTERVAL (NUMTOYMINTERVAL(1, 'MONTH'))
(PARTITION P_MAY2021 VALUES LESS THAN (202105));
As already mentioned you should never store date or time values as strings, use always proper DATE or TIMESTAMP data type.
As a workaround you can use VIRTUAL column like this:
CREATE TABLE T_ACCOUNT_PARTITION
(
V_ACCOUNT_NUM VARCHAR2(100 CHAR),
V_ACCOUNT_NAME VARCHAR2(200 CHAR),
ACC_DATE CHAR(6),
PARTITION_KEY TIMESTAMP(0) GENERATED ALWAYS AS (TO_TIMESTAMP(ACC_DATE, 'YYYYMM')),
)
PARTITION BY RANGE (PARTITION_KEY) INTERVAL (NUMTOYMINTERVAL(1, 'MONTH'))
(PARTITION P_MAY2021 VALUES LESS THAN (TIMESTAMP '2021-05-01 00:00:00'));

Get value from table oracle (xmltype)

How can i get xml data from a table,
CREATE TABLE PCRD_3DS_SOAP_LOGS
(
SERVICE_NAME VARCHAR2(50 BYTE) NOT NULL,
REQUEST_ID VARCHAR2(50 BYTE) NOT NULL,
ERROR_CODE CHAR(5 BYTE),
REQUEST SYS.XMLTYPE,
RESPONSE SYS.XMLTYPE,
USER_CREATE VARCHAR2(15 BYTE),
DATE_CREATE DATE,
USER_MODIF VARCHAR2(15 BYTE),
DATE_MODIF DATE
)
I get this error when I execute the select query:
select * from PCRD_3DS_SOAP_LOGS
Access violation at address 659A0C4B in module 'OraClient12.Dll'. Read of address 00000008
SELECT * FROM PCRD_3DS_SOAP_LOGS;
Should work, however, if Toad cannot handle the XMLTYPE data type then you can explicitly convert them to a string using XMLTYPE's getStringVal or getClobVal methods:
SELECT service_name,
request_id,
error_code,
p.request.getClobVal() AS request,
p.response.getClobVal() AS response,
user_create,
date_create,
user_modif,
date_modif
FROM PCRD_3DS_SOAP_LOGS p;
(You do need to include the table name or alias before the column name.)
db<>fiddle here

Creating and Populating the Time dimension

My shift_date column of my shift table has all the dates of the shift requests recieved by the agency.It contains other columns which shows whether the shift was filled or cancelled. I want to use this to create a time dimension and link to the fact table to find out how many shifts were filled each month,cancelled in a quarter,etc. i have created the time table as below. I am doing it in SQL developer and to understand dimensional modelling which I am having trouble getting my head around.
my shift table:
shift_date |shift_status|request_id|
-----------------------------------------
09-01-2011|Filled |8899
21-01-2011 |Cancelled |6677
and so on.
I created a time dimension table as below:
CREATE TABLE "DIM_TIME"
( "TIME_KEY" NUMBER(10,0),
"FULL_DATE" DATE,
"DAY_NAME" VARCHAR2(9 BYTE),
"DAY_OF_WEEK" NUMBER(5,0),
"DAY_NUMBER_IN_MONTH" NUMBER(2,0),
"DAY_NAME_ABBREVATED" VARCHAR2(5 BYTE),
"WEEKDAY_FLAG" VARCHAR2(2 BYTE),
"WEEK_OF_THE_YEAR" NUMBER(5,0),
"WEEK_BEGIN_DATE" DATE,
"MONTH_NUMBER" NUMBER(3,0),
"MONTH_NAME" VARCHAR2(20 BYTE),
"MONTH_ABBREVATED" VARCHAR2(5 BYTE),
"QUARTER" NUMBER(5,0),
"YEAR" NUMBER(5,0),
"LAST_DAY_IN_MONTH_FLAG" VARCHAR2(2 BYTE)
);
how can i extract the dates from the shift_date column to populate this time_dimension table? I am not expecting the whole code but if anyone can point me in the right direction it will be helpful as i am still learning.Thank you
This will create the rows in the DIM_TIME table:
create sequence s_time_key START WITH 1;
insert into dim_time (
time_key,
full_date,
day_name,
day_of_week,
day_number_in_month,
day_name_abbrevated,
weekday_flag,
week_of_the_year,
week_begin_date,
month_number,
month_name,
month_abbrevated,
quarter,
year,
last_day_in_month_flag
)
select
s_time_key.nextval,
d,
to_char(d,'Day'), --Monday
to_char(d,'D'), --1-7, monday=2 in some countries, 1 in others (NLS)
to_char(d,'DD'), --1-31
to_char(d,'Dy'), --Su, Mo, ...
decode(to_char(d,'Dy'),'Sa','N','Su','N','Y'),
to_char(d,'IW'), --week num ISO standard
--to_char(d,'WW'), --week num other
d+1-to_char(d,'D'), --first day in week, depending on NLS
to_number(to_char(d,'MM')),
to_char(d,'Month'),
to_char(d,'MON'),
to_char(d,'YYYYQ'),
to_char(d,'YYYY'),
decode(to_char(d+1,'DD'),'01','Y','N')
from (select distinct shift_date d from shift);
In Oracle 12c, instead of a sequence to get the time_key column, you could use create table dim_time ( time_key number(10) generated by default on null as identity, ... to autoincrement the key.
The select above will only populate table DIM_TIME with the dates that actually exists in table SHIFT. But often one will want all dates in a certain period, for instance all the days Jan 1st 2014 trough 2018 like this: replace the last line in the sql above with this:
.
from (
select d from (
select to_date('1970','YYYY')+level d from dual connect by level<=366*100
)
where to_char(d,'YYYY')
between 2014 and 2018
);
It's important to learn the to_char and to_date functions to handle dates in Oracle. https://www.techonthenet.com/oracle/functions/to_char.php

SQL Query to count entire duplicate row

I am looking for help with a query to do the following:
Before the insert of a row, find how many rows in 2 tables have the same information as is being inserted.
So basically I am looking to see if this row will be a complete duplicate.
I want to base this on all the columns, not just the PK, because if there is even one column different then this is a valid insert.
This is something along the lines of what I need, although incorrect:
SELECT COUNT(*)
FROM ORDER_TRF_HEADER
WHERE
((SELECT * FROM ORDER_TRF_HEADER_COMPLETE WHERE MA_PONUM = '29608207') = (SELECT * FROM ORDER_TRF_HEADER WHERE MA_PONUM = '29608207'));
Table - ORDER_TRF_HEADER
MA_CUST VARCHAR2(8 BYTE)
MA_PONUM VARCHAR2(30 BYTE)
MA_ODATE VARCHAR2(8 BYTE)
MA_ITEMS NUMBER(3,0)
MA_SALEM VARCHAR2(2 BYTE)
MA_PDAYS NUMBER(3,0)
MA_CURR VARCHAR2(3 BYTE)
Table - ORDER_TRF_HEADER_COMPLETE
MA_CUST VARCHAR2(8 BYTE)
MA_PONUM VARCHAR2(30 BYTE)
MA_ODATE VARCHAR2(8 BYTE)
MA_ITEMS NUMBER(3,0)
MA_SALEM VARCHAR2(2 BYTE)
MA_PDAYS NUMBER(3,0)
MA_CURR VARCHAR2(3 BYTE)
Thanks
I want to base this on all the columns, not just the PK, because if there is even one column different then this is a valid insert.
then your issue is that you have NOT defined your primary key correctly.
Certainly there are good reasons for not maintaining a primary key consisting of every attribute in the record, however a better solution than checking for duplicates in such a clumsy way before inserting would be to maintain a has of the data as a unique key.
You can try INTERSECT.
SELECT COUNT(*)
FROM (SELECT *
FROM order_trf_header_complete
WHERE ma_ponum = '29608207'
INTERSECT
SELECT *
FROM order_trf_header
WHERE ma_ponum = '29608207') ;
Note:: You better use all column names explicitly instead of select *

Date Format Options in Oracle External Table

I have created an external table, everything looks good except for one of the date format, it looks like it defaults to MM/DD/YYYY but I want it as YYYYMMDD as it is in the file. The column is DATE_ID. Anyone have any clues?
Thanks!
CREATE TABLE R2SCHD.AAFES_RDF_XTRNL_CAL_HIER
(
DATE_ID DATE,
DATE_DESC DATE,
WEEK_ID VARCHAR2(25 BYTE),
WEEK_DESC DATE,
MNTH_ID VARCHAR2(25 BYTE),
MNTH_DESC VARCHAR2(25 BYTE),
QRTR_ID VARCHAR2(25 BYTE),
QRTR_DESC VARCHAR2(25 BYTE),
HALF_ID VARCHAR2(25 BYTE),
HALF_DESC VARCHAR2(25 BYTE),
YEAR_ID VARCHAR2(25 BYTE),
YEAR_DESC VARCHAR2(25 BYTE),
DOW_ID VARCHAR2(25 BYTE),
DOW_DESC VARCHAR2(25 BYTE)
)
ORGANIZATION EXTERNAL
( TYPE ORACLE_LOADER
DEFAULT DIRECTORY R2SCHD_STATIC_DATA
ACCESS PARAMETERS
( RECORDS DELIMITED BY NEWLINE
NOBADFILE
NOLOGFILE
NODISCARDFILE
FIELDS TERMINATED BY ','
MISSING FIELD VALUES ARE NULL
(
DATE_ID CHAR(8) DATE_FORMAT DATE MASK "YYYYMMDD",
DATE_DESC CHAR(10) DATE_FORMAT DATE MASK "MM/DD/YYYY",
WEEK_ID,
WEEK_DESC CHAR(10) DATE_FORMAT DATE MASK "MM/DD/YYYY",
MNTH_ID, MNTH_DESC, QRTR_ID, QRTR_DESC, HALF_ID,
HALF_DESC, YEAR_ID, YEAR_DESC, DOW_ID, DOW_DESC
)
)
LOCATION (R2SCHD_STATIC_DATA:'rdft_cal_external.dat')
)
REJECT LIMIT UNLIMITED
NOPARALLEL
NOMONITORING;
You created the date_id as DATE data type, which is correct. Dates do not have a "format" - what you see on your screen, with slashes, is dictated by your NLS_DATE_FORMAT setting. What are you using - SQL*Plus? SQL Developer? Toad?
For example in SQL Developer: Tools - Preferences - Database - NLS and you will see (and be able to change) your date format. That is what controls what is shown on your screen - not the format you used for your external table (it won't help you to set it as 'YYYYMMDD' there).