Updates values from column in SQL - sql

Im trying to change the value from the Merchant_Category_Code column.
I tried CASE Statement but didn't work.
CASE
WHEN MERCHANT_CATEGORY_CODE = 6051 THEN 'Quasi Cash–Merchant'
WHEN MERCHANT_CATEGORY_CODE = 4829 THEN 'Wire Transfer Money Orders & Money Transfer'
WHEN MERCHANT_CATEGORY_CODE = 6012 THEN 'Member Financial Institution–Merchandise And Services'
WHEN MERCHANT_CATEGORY_CODE = 6011 THEN 'Member Financial Institution–Automated Cash Disbursements'
WHEN MERCHANT_CATEGORY_CODE = 7372 THEN 'Computer Programming, Data Processing and Integrated System Design Services'
WHEN MERCHANT_CATEGORY_CODE = 5812 THEN 'Eating Places and Restaurants'
WHEN MERCHANT_CATEGORY_CODE = 5817 THEN 'Digital Goods: Applications (Excludes Games)'
WHEN MERCHANT_CATEGORY_CODE = 3010 THEN 'Royal Dutch Airlines (KLM Airlines)'
WHEN MERCHANT_CATEGORY_CODE = 3007 THEN 'Air France'
WHEN MERCHANT_CATEGORY_CODE = 5735 THEN 'Record Shops'
ELSE 'CHECK'
END AS MERCHANT_CATEGORY_CODE_DETAIL
Also,UPDATE but same result:
UPDATE "RED"."TRANSACTIONS"
SET MERCHANT_CATEGORY_CODE=3035
,MERCHANT_CATEGORY_CODE='TAP Air Portugal (TAP)';
Here the screenshot from the table I want to change values:
Want to rename the values from this column

It doesn't make any sense to be attempting to assign string values to the MERCHANT_CATEGORY_CODE column given that it is some numeric type. Assuming you want to assign the description to a text column, you may update via a CASE expression as follows:
UPDATE "RED"."TRANSACTIONS"
SET MERCHANT_CATEGORY_CODE_DETAIL = CASE MERCHANT_CATEGORY_CODE
WHEN 6051 THEN 'Quasi Cash–Merchant'
WHEN 4829 THEN 'Wire Transfer Money Orders & Money Transfer'
WHEN 6012 THEN 'Member Financial Institution–Merchandise And Services'
WHEN 6011 THEN 'Member Financial Institution–Automated Cash Disbursements'
WHEN 7372 THEN 'Computer Programming, Data Processing and Integrated System Design Services'
WHEN 5812 THEN 'Eating Places and Restaurants'
WHEN 5817 THEN 'Digital Goods: Applications (Excludes Games)'
WHEN 3010 THEN 'Royal Dutch Airlines (KLM Airlines)'
WHEN 3007 THEN 'Air France'
WHEN 5735 THEN 'Record Shops'
ELSE 'CHECK' END;

Just a FYI --- this is a better way to to do this translation in SQL -- joins are faster than a case statement:
SELECT MERCHANGE_CATEGORY_CODE,
COALESCE(T.DESCR,'CHECK') AS MERCHANT_CATEGORY_CODE_DETAIL
FROM SOMETABLE
LEFT JOIN (
VALUES
(6051, 'Quasi Cash–Merchant'),
(4829, 'Wire Transfer Money Orders & Money Transfer'),
(6012, 'Member Financial Institution–Merchandise And Services'),
(6011, 'Member Financial Institution–Automated Cash Disbursements'),
(7372, 'Computer Programming, Data Processing and Integrated System Design Services'),
(5812, 'Eating Places and Restaurants'),
(5817, 'Digital Goods: Applications (Excludes Games)'),
(3010, 'Royal Dutch Airlines (KLM Airlines)'),
(3007, 'Air France'),
(5735, 'Record Shops')
) AS T(CODE,DESCR) ON SOMETABLE.MERCHANT_CATEGORY_CODE = T.CODE

Related

SQL Query(ies) to Gather Data for Common Business Reports

I have a database with a 'General Ledger', 'Account Types' and 'Chart of Accounts' tables. The layout is as follows:
'Account Types':
AcctTypeID Autonumber Long Integer Not Null Primary Key
TypeName Text(50) Not Null
Description Memo
Credit Yes/No Not Null Default Yes
'Chart of Accounts':
AcctID Long Integer Not Null Primary Key
AcctName Text(30) Not Null
Description Memo
AcctType Long Integer Not Null
'General Ledger':
EntryID Autonumber Long Integer Not Null Primary Key
EntryDate Date/Time Not Null Default #1/1/1900#
EntryType Text(12) Not Null Default "DC"
Description Memo
FromAcct Long Integer Not Null
ToAcct Long Integer Not Null
Taxable Yes/No Not Null Default No
Relationships Between Tables:
One-to-Many from 'Chart of Accounts'->AcctID to 'General Ledger'->FromAcct
One-to-Many from 'Chart of Accounts'->AcctID to 'General Ledger'->ToAcct
One-to-Many from 'Account Types'->TypeID to 'Chart of Accounts'->AcctType
I'm needing to start by fulfilling the following requirements in two different SQL queries:
If ToAcct.AcctType == (Income OR Asset) then add 'General Ledger'.Amount to a TotalRevenue
If ToAcct.AcctType == (Expense OR Liability) then add 'General Ledger'.Amount to TotalExpenses
I've tried these two SQL queries, before I modified my 'Account Types' to include whether they are income/assets or expenses/liabilities:
SELECT SUM(IIF((Credit = TRUE), Amount, 0)) AS RevenueTotal FROM GeneralLedger;
SELECT SUM(IIF((Credit = FALSE), Amount, 0)) AS ExpenseTotal FROM GeneralLedger
These queries worked, but I had the extra checkbox on the General Ledger form for "Credit". In normalizing, I figured it would be better for the account to determine whether it is a debit or a credit account.
After multiple searches on Google and reading I-don't-know-how-many questions and answers, I'm not seeing anything that is similar to what I'm trying to do here.
The output should give me the information needed for creating the Profit & Loss, Income Statement, Business and Tax reports. I believe I can get the SQL queries going for pulling the amounts based on their account, but I'm not sure how to get at the account types' 'Debit' field to determine whether to add or subtract the amount.
If necessary, I may do this inside the C# application that this database will underpin. If I can do it at the SQL Query level, I'd be able to use it in the project as a view, instead of having to code it. Any help at all is greatly appreciated.
After a couple more searches, I found my answer as being that I need to do 4 different queries to accomplish what I was attempting. The appropriate queries turned out to be:
For Total Expenses:
SELECT SUM(Amount) AS TotalExpense
FROM GeneralLedger INNER JOIN ChartOfAccounts ON ChartOfAccounts.AcctID=GeneralLedger.ToAcct
WHERE ChartOfAccounts.AcctType = 4;
For Total Revenue:
SELECT SUM(Amount) AS TotalRevenue
FROM GeneralLedger INNER JOIN ChartOfAccounts ON ChartOfAccounts.AcctID=GeneralLedger.ToAcct
WHERE ChartOfAccounts.AcctType = 3;
For Total Liabilities:
SELECT SUM(Amount) AS TotalLiabilities
FROM GeneralLedger INNER JOIN ChartOfAccounts ON ChartOfAccounts.AcctID = GeneralLedger.ToAcct
WHERE ChartOfAccounts.AcctType = 2;
For Total Assets:
SELECT SUM(Amount) AS TotalAssets
FROM GeneralLedger INNER JOIN ChartOfAccounts ON ChartOfAccounts.AcctID = GeneralLedger.ToAcct
WHERE ChartOfAccounts.AcctType = 1;
It was just a matter of getting my INNER JOIN working with my WHERE clause properly. It's the simple things that kill...
The link that proved most helpful was: StackOverflow: sql - INNER JOIN WHERE clause.

SQL-Server drill down in an other table (group by)

OK, I'm quite new to SQL and didn't get to much training!
I'm using SSMS to create stored procedures and open them in Excel.
The code below work just fine, but I need to add a drill down to get more info on some lines.
We need to follow what was invoice and paid on a batch of contracts for our project. Each contract have multiple lines with a description and a couple of other fields(reference, line #, G/L # etc). Plus we have the value of the line, the amount that was invoice for this line and the amount that was paid.
Main table 'CSCOMVTL' have the basic infos including the base value and the invoice amount, but not the paid amount.
'JRAPRVTL' is the list of all invoices with; invoice no., invoice date, invoiced amount and paid amount that we may need to see.
So for each base line, we need a +/- button to show/hide details of the invoice.
Invoice amount and paid amount could be from a rollup, but the number and date won't be on the parent line. If they could be in the same column as other field not needed it would be great, but I could live with 2 extra columns.
Thanks!
ALTER PROCEDURE [dbo].[marpt_qmd_AccPmt_DetailsST]
#contrat varchar(30), #projet varchar(30)
AS
BEGIN
CREATE TABLE #RPT
(
Ligne INT,
Lien INT,
Act VARCHAR (10),
Descr VARCHAR (90),
MntBase DECIMAL (20,2),
MntFact DECIMAL (20,2),
Modif VARCHAR (40),
Descr3 VARCHAR (90),
Lien2 INT,
MntPy DECIMAL (20,2) default '0',
)
INSERT INTO #RPT (Ligne, Lien, Act, Descr, MntBase, MntFact)
SELECT ROW, DETAILCHANGEORDERCOU, ACTIVITY, DESCRIPTION, AMOUNT, INVOICE
FROM cscomvtl
WHERE PROJECTNUMBER = #projet
and LTRIM(RTRIM(PONUMBER)) = #contrat
UPDATE #RPT
SET Modif=m.CHANGEORDERNUMBER, Descr3=m.DESCRIPTION, Lien2=m.CHANGEORDERCOUNTER
FROM cscomac m, #RPT r
where m.COUNTER=r.Lien
UPDATE #RPT
SET MntPy=payment
FROM #RPT r, (select POLINE, sum(payment) payment from jraprvtl where PROJECTNO=#projet
and LTRIM(RTRIM(PURCHASEORDER))=#contrat group by POLINE) d
where r.Ligne=d. POLINE
SELECT
Ligne as 'Ligne',
Act as 'Act.',
Descr as 'Description 1',
MntBase as '$ Base',
MntFact as '$ Invoiced',
Modif as 'Num. Modif.',
Descr3 as 'Description 2',
MntPy as '$ Paid'
FROM #RPT
Order by Ligne
Drop table #RPT
First off, take the time & learn SQL. It's an invaluable tool in your toolkit!
Okay, enough of the lecture. In looking through your code, you don't seem to really need the temp table #rpt, you just need to understand JOINs. Hopefully this SQL will get you what you are looking for:
SELECT vtl.ROW AS Ligne, vtl.DETAILCHANGEORDERCOU AS Lein, vtl.ACTIVITY AS Act,
vtl.DESCRIPTION AS Descr, vtl.AMOUNT AS MntBase, vtl.INVOICE AS MntFact,
mac.CHANGEORDERNUMBER AS Modif, mac.DESCRIPTION AS Descr3, mac.CHANGEORDERCOUNTER AS Lien2,
sum(jrap.payment) AS MntPy
FROM cscomvtl AS vtl
LEFT OUTER JOIN cscomac AS mac
ON vtl.detailchangeordercou = mac.counter
LEFT OUTER JOIN jraprvtl AS jrap
ON vtl.row = jrap.poline
WHERE projectnumber = #projet AND LTRIM(RTRIM(ponumber)) = #contrat
GROUP BY vtl.row, vtl.detailchangeordercou, vtl.activity, vtl.description, vtl.amount,
vtl.invoice, mac.changeordernumber, mac.description, mac.changeordercounter
You will likely have to tweak it to fit what you're trying to do in Excel, since you really didn't give much to go on there.

Update substring in column with dynamic value in table

I have 1 column in a table with value like below:
Activation period=0#Actual pay channel=214952491#Agreement id=1115151#Alternative charge code description=Fido Internet 75 - illimité
#Alternative packaging code description= #Alternative saving code description=Offre Fido Internet#Apply additional discount=N
#BCB ind=N#BCB seq no=0#Base charge amount=57.00000#Base offer ID=505613187#Base offer instance ID=5194671#Base offer item ID=505613107
#Bill frequency=1#Bulk billing code=Permanent#Business entity=0#Charge description=Fido Internet 75 - Unlimited#Charge identifier=D
#Charge nullify by discount ind=Y#Charge type=DSC#Check restriction ind=N#Commercial or residential=Residential#Commission id=006020
#Commitment end date=#Commitment period=#Commitment start date=#Component code=HS#Contract code=0#Contract desc code= #Contract dummy RC ind=N
#Contract revenue type=RC#CurrentCycleEndDate=00000000#CurrentCycleStartDate=00000000#Customer sub type=R#Customer type=F#Dealer code=CC
#Discount item ID=505613217#Discount type=NONE#Display charge ind= #Dummy ind=N#Dummy quotation ind=N#Dwelling code=07
#Equipment serial number= #Foreign manufacturer= #Foreign model= #Franchise=RCM#Included ind=N#LPIF indicator=N#Line of business=Internet
#Map area= #Multi dweling/single unit=MDU#Notification indicator=Y#Number of occurences=0#Occurrence in order=0#Offer connect Date=20180403
#Offer name=HS Fido Internet Embedded Discount 2018 - 3MF discount HS ACQ CON#Order id=10173580#Orig charge ind=N#Orig charge seq no=0
#Orig discount amount=0#Original charge amount=-57.00000#Original commitment start date=20201231#Override RC indicator=N#Override policy=N
#PRIT name=HS Fido Internet Embedded Discount 2018 - 3MF discount HS ACQ CON - RC Discount#Packaging code= #Packaging description= #Period scale=0
#Printing charge ind= #Product offer ID=505618817#Promotion effective date=20180403#Promotion expiration date=20180703#Promotion indicator=Y
#Quantity=1#RC expiration date=20180704#Rate=-57.00000#Rate area=RCM#Relation type= #Retrieve exemption=Y#SAM key=2330000367541#Sales channel=
#Savings code=SC_CM_R_G9CSSSS#Savings description=Fido Internet Offer#Scale type=D#Service province=ON#Subscriber status=A#Subscriber sub type=Z
#Subscriber type=HS#Taxable amount=-57.00000#Waive ind= #
Here, i need to update "Promotion expiration date" value with the new one. How can i do it using update command.
Please help me with the command how to achieve this result?
Thanks
I prefer using simple string functions like INSTR, SUBSTR and REPLACE, but in this case it is much more readable with a simple REGEXP-REPLACE:
with testtab as(
select '[...]#Product offer ID=505618817#Promotion effective date=20180403#Promotion expiration date=20180703#Promotion indicator=Y
#[...]#Waive ind= #' as text from dual)
select regexp_replace(text, 'Promotion expiration date=\d*', 'Promotion expiration date=' || to_char(sysdate, 'YYYYMMDD') ) from testtab;
\d* is a 0 to infinite amout of numbers like '', 345345 or 4356456345634563546. It matches untill the #. This means that it replaces Promotion expiration date=20180606 as well as Promotion expiration date=345665756567

How to get financials of firms listed at TESA in quantmod?

I'm trying to retrieve financials for firms listed at Tel Aviv Stock Exchange, e.g.: LUMI (Bank Leumi), by quantmod using source=yahoo.
Here is the error I get:
getFin("LUMI",src="yahoo")
Error in thead[x]:thead[x + 1] : NA/NaN argument
I also tried:
getFin("LUMI.TA",src="yahoo")
Error in thead[x]:thead[x + 1] : NA/NaN argument
It seems that getFin does not work for foreign firms, any lead?
First query: Check if the symbol you are searching in Google Finance has financials (as a link/tab) under the Company tab on the left.
getFin/getFinancials is essentially query searching for this through the API configuration.
Also, note that yahoo is overridden by google even after assigning src = "yahoo". Check ?getFin in the console to confirm. It says under the description in help: Download Income Statement, Balance Sheet, and Cash Flow Statements from Google Finance.
If the company's financial statements are not recorded under the U.S. Securities and Exchange Commission, check here: SEC: Enter Company Symbol under Fast Search to see if the European company has filings under the SEC.
For example NVS - Novartis works, unlike LUMI or Nestlé (NSRGY).
library(quantmod)
myData <- new.env()
class(myData)
ls(myData)
NVS <- getFinancials('NVS', env = myData, src = "yahoo", auto.assign=TRUE)
viewFinancials(NVS.f, type= 'IS', period = 'Q') #Options `type=c('BS','IS','CF'), period=c('A','Q')`
Output from: viewFinancials(NVS.f, type= 'IS', period = 'Q') (Truncated output data for view purposes).
> viewFinancials(NVS.f, type= 'IS', period = 'Q')
Quarterly Income Statement for NVS
2014-12-31 2014-09-30 2014-06-30
Revenue 13354.00 13300.00 26980.00
Other Revenue, Total NA NA NA
Total Revenue 13354.00 13300.00 26980.00
Cost of Revenue, Total 4416.00 4421.00 8508.00
Gross Profit 8938.00 8879.00 18472.00
Selling/General/Admin. Expenses, Total 3965.00 3565.00 7463.00
Research & Development 2537.00 2161.00 4388.00
You can get what you need off the BS, IS, or CF by doing the following:
> NVS_Q <- viewFinancials(NVS.f, type= 'IS', period = 'Q')
Quarterly Income Statement for NVS
> Revenue2014_12_31 <- NVS_Q[1,1]
> Revenue2014_12_31
[1] 13354

How can I modify my SQL subquery to get my query to work?

So basically, I know SQL doesn't allow this, but I wish I could do this because it's the only way I can think of to make my query.
So for example, say that there are 2 delivery trucks heading to the address '55 Alaska Rd.' with some items to deliver.
1 truck has 100 iPads and 200 iPhones
1 truck has 150 iPads
I am happily monitoring them by running this query:
[select truck.truck_id,
truck.driver_name,
truck.current_location,
item.prtnum,
item.quantity
from truck,
box,
item,
shipment
where item.box_id = box.box_id
and box.truck_id = truck.truck_id
and truck.ship_adr = shipment.ship_adr
and shipment.ship_adr = '55 Alaska Rd.']
It tells me who my 2 guys are, their current location, and what they're carrying. It returns 3 rows:
| Truck ID | Driver Name | Current Location | Item Number | Item Quantity |
|---TRK83--|---Gene R.---|------Hwy 18------|----iPad-----|------100------|
|---TRK83--|---Gene R.---|------Hwy 18------|---iPhone----|------200------|
|---TRK59--|---Jill M.---|------Hwy 894-----|----iPad-----|------150------|
Then my manager calls me and DEMANDS that I send him this same query, but modified so that it only returns trucks that have 1 item on it. So in this instance, he only wants the last row to be returned, because it only has iPads on it, and the other one has iPads and iPhones.
This is how I wish I could do it.
[select t.truck_id,
t.driver_name,
t.current_location,
i.prtnum,
i.quantity
from item i,
box b,
truck t,
shipment s
where i.box_id = b.box_id
and b.truck_id = t.truck_id
and t.truck_id in (select tr.truck_id,
decode(max(it.prtnum), min(it.prtnum), max(it.prtnum), 'Mixed Items') prtnum
from item it,
box bo,
truck tr
where it.box_id = bo.box_id
and bo.truck_id = tr.truck_id
and tr.truck_id = t.truck_id
and prtnum != 'Mixed Items'
group by tr.truck_id) p
and t.ship_adr = s.ship_adr
and s.ship_adr = '55 Alaska Rd.']
That subquery is supposed to be selecting only the trucks in the parent query that do not have Mixed Parts on it. But that doesn't work because:
I can only have "tr.truck_id" in the subquery select; the decode can't also be there, but I don't know where else to put it.
I can't use the alias "prtnum" like that.
Does anyone know how I can achieve what my hypothetical boss wants me to do? Does anyone have any ideas on how I can alter the query to make it only select the trucks that have 1 item in it? I am going to have to change a lot of queries to do this, and I just can't figure out a good clean way. Or even a bad way that works.
Thank you for reading, and thank you for any help!
You can create a group for each truck, and then per truck, demand that they carry only one type of item. Group-wide conditions are set with the having clause. Here's an example:
select truck.truck_id
, truck.driver_name
, truck.current_location
, sum(item.quantity) as sum_quantity
from truck
join box
on box.truck_id = truck.truck_id
join item
on item.box_id = box.box_id
where truck.ship_adr = '55 Alaska Rd.'
group by
truck.truck_id
, truck.driver_name
, truck.current_location
having count(distinct item.prtnum) = 1 -- Only one item type for this truck
There's no need to join the shipment table. You can use the ship_adr from the truck table to filter on address.
I've added the sum of all quantities per truck to show how you can display group-wide statistics in addition to filtering on them.
Not having your dataset makes it a bit awkward but, as you only want the single count rows a GROUP BY with a trailing HAVING clause may fix the problem:
SELECT truck.truck_id,
truck.driver_name,
truck.current_location,
item.prtnum,
item.quantity
FROM truck,
box,
item,
shipment
WHERE item.box_id = box.box_id
AND box.truck_id = truck.truck_id
AND truck.ship_adr = shipment.ship_adr
AND shipment.ship_adr = '55 Alaska Rd.'
GROUP BY truck.truck_id,
truck.driver_name,
truck.current_location
HAVING COUNT(item.quantity) = 1
Sounds like a job for analytic functions:
with truck_info as (select truck.truck_id,
truck.driver_name,
truck.current_location,
item.prtnum,
item.quantity,
count(item.prtnum) over (partition by truck.truck_id, truck.driver_name, truck.current_location) cnt
from truck,
box,
item,
shipment
where item.box_id = box.box_id
and box.truck_id = truck.truck_id
and truck.ship_adr = shipment.ship_adr
and shipment.ship_adr = '55 Alaska Rd.')
select truck_id,
driver_name,
current_location,
prtnum,
quantity
from truck_info
where cnt = 1;
N.B. untested
If you've never come across analytic functions before, they're well worth learning about!