sql routine to export separate txt files - sql

I have an sql query which is a pricelist that I normally run 18 different times for 18 different clients.
I have a #varchar as as declaration and I change the customerID. This then exports a txt flat-file file so then I can convert to Excel and send via feebootimail.
Is there a routine that I can run in sql 2005 so I can feed a list of customers into and get 18 different txt files? example Pricelist_8343.txt, Pricelist_8363.txt ect
DECLARE #CustNum varchar(20)
SELECT #CustNum = '7509'
SELECT
it.ITEMID 'item id'
,it.ItemGroupID
,it.ITEMNAME
,Convert(Decimal(9,0),itm.QUANTITY) 'Sales Multiple'
,Convert(Decimal(9,0),it.TAXPACKAGINGQTY) 'Price Break Qty'
,Convert(Decimal(9,0),it.OUTERQUANTITY) 'Carton Qty'
,Convert(Decimal(9,2),itm.PRICE) 'Part Pack'
,Convert(Decimal(9,2),itm.PRICE2) 'Full Pack'
,Convert(Decimal(9,2),round( CASE
WHEN pdt.AMOUNT >0 then pdt.amount
else CASE
when pdt.discpct is null then CASE
WHEN pdt.PRICELEVELTOUSE = 0 then Price
WHEN pdt.PRICELEVELTOUSE = 1 then Price2
WHEN pdt.PRICELEVELTOUSE = 2 then Price3
WHEN pdt.PRICELEVELTOUSE = 3 then Price4
WHEN pdt.PRICELEVELTOUSE = 4 then Price5
WHEN pdt.PRICELEVELTOUSE = 5 then Price6 END
when pdt.discpct = 0 then CASE
WHEN pdt.PRICELEVELTOUSE = 0 then Price
WHEN pdt.PRICELEVELTOUSE = 1 then Price2
WHEN pdt.PRICELEVELTOUSE = 2 then Price3
WHEN pdt.PRICELEVELTOUSE = 3 then Price4
WHEN pdt.PRICELEVELTOUSE = 4 then Price5
WHEN pdt.PRICELEVELTOUSE = 5 then Price6 END
when pdt.discpct > 0 then CASE
WHEN pdt.PRICELEVELTOUSE = 0 then round(itm.price - (itm.price*pdt.discpct/100),2)
WHEN pdt.PRICELEVELTOUSE = 1 then round(itm.price2 - (itm.price2*pdt.discpct/100),2)
WHEN pdt.PRICELEVELTOUSE = 2 then round(itm.price3 - (itm.price3*pdt.discpct/100),2)
WHEN pdt.PRICELEVELTOUSE = 3 then round(itm.price4 - (itm.price4*pdt.discpct/100),2)
WHEN pdt.PRICELEVELTOUSE = 4 then round(itm.price5 - (itm.price5*pdt.discpct/100),2)
WHEN pdt.PRICELEVELTOUSE = 5 then round(itm.price6 - (itm.price6*pdt.discpct/100),2) END END END ,2)) as 'TAPrice'
,upper(itm.unitid) 'UOM'
, Case
When itm.PRICECHANGESTATUS=3 then 'Increase'
When itm.PRICECHANGESTATUS=2 then 'Decrease'
When itm.PRICECHANGESTATUS=1 then 'New Item'
When itm.PRICECHANGESTATUS=0 then '-'
END 'Price Indicator'
from INVENTTABLE it
join INVENTTABLEMODULE itm on it.ItemId = itm.ItemID and itm.ModuleType = 2
join CUSTTABLE cust on LTRIM(cust.AccountNum) = #CustNum
left outer join PRICEDISCTABLE pdt on (ltrim(pdt.accountrelation) =
case
when pdt.accountcode = 0 then ltrim(cust.accountnum)
when pdt.accountcode = 1 then ltrim(cust.pricegroup) end)and
(ltrim(pdt.ItemRelation)+ltrim(pdt.UnitID) = case
when pdt.itemrelation = it.itemid then ltrim(it.ItemID)+ltrim(itm.Unitid)
when pdt.itemrelation = it.itempricegroup then ltrim(it.ItemPriceGroup)+ltrim(itm.Unitid)end
) and pdt.fromdate <= getdate() and (getdate()<= pdt.todate or pdt.todate = ' ')
join PriceLevelListReportLine sorter on it.ItemGroupID = sorter.ItemGroupID
and (it.ItemType = (case when sorter.linetype = 0 then '0'
when sorter.linetype = 1 then '0'
when sorter.linetype = 2 then '1'end)
or it.ItemType = (case when sorter.linetype = 1 then '1' end))
WHERE it.PRICELISTFlag=1
ORDER BY sorter.SortOrder, it.ItemID

You could do this with SQLCMD and a batch file.
Make a script.sql file with contents like:
declare #CustNum varchar(20) = '$(custnum)'
select
-- your giant query here
Then make a batch file that looks like this:
#echo off
set custnum=1234
call :export
set custnum=5678
call :export
set custnum=9012
call :export
goto :eof
:export
sqlcmd -E -i script.sql -o %custnum%.txt -v CustNum=%custnum%
goto :eof
Copy and paste the set/call lines once for each of your 18 customers.
Instead of copy+paste, you could do something with a for loop if you have a list of the customers somewhere - output of another SQLCMD query, or just a text file. I leave that to you to figure out.

Related

SQL - JOIN with condition CASE - how to make - if condition is met stop to meet next one

Cashier can input to field C40_DATA 3 different values (9962**********, id_invoice, web_order)
what I would like to have as result:
if substr from C40_DATA contains p.id_invoice => show these lines
if C40_contains contains id_web_order or id_incvoice => show these lines
-> it means point 1 shows always but point 2 -> do not show both, if exist id_web_order, show it and stop, if it not exists find id_incvoice
When I create this (below), result contains all 3 together, but I need 1 + (if exist 2 and if not find 3)
select * from web_data p
inner join POS_DATA re on
(case
when substr(re.C40_DATA,5,8) = p.id_invoice and substr(re.C40_DATA,1,4) ='9962' then 1 else
(case
when re.C40_DATA = p.id_web_order and p.d_mnozstvi < '0' then 1 else
(case
when re.C40_DATA = p.id_invoice and p.d_mnozstvi < '0' then 1 else 0 END)
END)
END=1)
Could you please help how to make contitions in JOINs which do - if one condition is met stop and do not find the next one?
Thank you,
Your attempted query would have been better written this way:
select * from web_data p
inner join POS_DATA re on
substr(re.C40_DATA, 5, 8) = p.id_invoice and substr(re.C40_DATA, 1, 4) = '9962'
or re.C40_DATA = p.id_web_order and p.d_mnozstvi < '0'
or re.C40_DATA = p.id_invoice and p.d_mnozstvi < '0'
Had you really needed to do this as a case expression it could have been done as below. The cases fall through in order:
case
when substr(re.C40_DATA, 5, 8) = p.id_invoice and substr(re.C40_DATA, 1, 4) ='9962' then 1
when re.C40_DATA = p.id_web_order and p.d_mnozstvi < '0' then 1
when re.C40_DATA = p.id_invoice and p.d_mnozstvi < '0' then 1
end = 1
As far as matching only on a single condition, I think you want something like this:
with data as (
select *,
case
when re.C40_DATA = '9962' + p.id_invoice then 1
when re.C40_DATA = p.id_web_order and p.d_mnozstvi < '0' then 2
when re.C40_DATA = p.id_invoice and p.d_mnozstvi < '0' then 3
end as match_rank,
min(case
when re.C40_DATA = '9962' + p.id_invoice then 1
when re.C40_DATA = p.id_web_order and p.d_mnozstvi < '0' then 2
when re.C40_DATA = p.id_invoice and p.d_mnozstvi < '0' then 3
) over (partition by p.id_invoice, p.web_order) as min_match_rank
from web_data p
inner join POS_DATA re on
re.C40_DATA = '9962' + p.id_invoice
or re.C40_DATA = (p.id_web_order, p.id_invoice) and p.d_mnozstvi < '0'
)
select * from data where match_rank = min_match_rank;
I've taken the liberty of rewriting some of your conditions in case those options are useful to you. Also, I'm not sure what < '0' is supposed to mean. Finally, I'm not sure which values to be partitioning over because I don't understand the relationship between id_invoice and id_web_order.

display the total based on the inputted amount in the datagridview

i have a textbox where i can input any amount for example 3,000.00, then a datagridview that looks like
Category | Amount
Supmat | 2,000
POL | 500
Others | 400
POL | 500
to get the total i used this code
For i As Integer = 0 To DataGridView1.RowCount - 1
If DataGridView1.Rows(i).Cells("Category").Value = "Supplies/Materials" Then
supmat += DataGridView1.Rows(i).Cells("Amount").Value
ElseIf DataGridView1.Rows(i).Cells("Category").Value = "Legal Expenses" Then
legal += DataGridView1.Rows(i).Cells("Amount").Value
ElseIf DataGridView1.Rows(i).Cells("Category").Value = "POL" Then
pol += DataGridView1.Rows(i).Cells("Amount").Value
ElseIf DataGridView1.Rows(i).Cells("Category").Value = "Others" Then
oth += DataGridView1.Rows(i).Cells("Amount").Value
End If
If CDec(txtFund.Text) > supmat Then
supmat1 = supmat
remain = CDec(txtFund.Text) - supmat
If legal > 0 Then
If remain > legal Then
legal1 = legal
remain2 = remain - legal
If pol > 0 Then
If remain2 > pol Then
pol1 = pol
remain3 = remain2 - pol
If oth > 0 Then
If remain3 > oth Then
oth1 = oth
Else
oth1 = remain3
End If
Else
oth1 = remain3
End If
Else
pol1 = remain2
oth1 = 0
End If
ElseIf oth > 0 Then
If remain2 > oth Then
oth1 = oth
Else
oth1 = remain2
End If
End If
Else
legal1 = remain
pol1 = 0
oth1 = 0
End If
ElseIf pol > 0 Then
If remain > pol Then
pol1 = pol
remain2 = remain - pol
If oth > 0 Then
If remain2 > oth Then
oth1 = oth
Else
oth1 = remain2
End If
Else
oth1 = remain2
End If
Else
pol1 = remain
oth1 = 0
End If
ElseIf oth > 0 Then
If remain > oth Then
oth1 = oth
Else
oth1 = remain
End If
End If
Else
supmat1 = CDec(txtFund.Text)
legal1 = 0
pol1 = 0
oth1 = 0
End If
Next
i got the total of 3000 where the output is
Supmat = 2000
Legal = 0
POL = 1000
Others = 0
but the output i need is
Supmat = 2000
Legal = 0
POL = 600
Others = 400
if you check my category i inputted the Supmat 2000 first then POL 500 then Others 400 and last is POL 500 again. i only need to get the total of 3000 but since the last POL is 500 i should only get the 100 from it. since i already have the 2000 + 500 + 400 from the first three.
can someone help with the code where whatever i inputted in my datagridview that should be displayed first instead of getting the total of every category.
sample picture
I attached a sample picture on how i want my output is.
the code above can do the output
Supmat = 2000
Legal = 0
POL = 1000
Others = 0
Try this... Loop thru your data passing the total value and each subtotal value to calcTotal which handles the actual calculations and updates the totals. When the total value <= 0, exit the loop.
Private Sub MainCalculation()
Dim supmat As Decimal = 0
Dim legal As Decimal = 0
Dim pol As Decimal = 0
Dim oth As Decimal = 0
Dim total_value As Decimal = CDec(Me.txtFund.Text)
For i As Integer = 0 To DataGridView1.RowCount - 1
Dim t As Decimal = DataGridView1.Rows(i).Cells("Amount").Value
Select Case DataGridView1.Rows(i).Cells("Category").Value
Case "Supplies/Materials"
calcTotal(supmat, total_value, t)
Case "Legal Expenses"
calcTotal(legal, total_value, t)
Case "POL"
calcTotal(pol, total_value, t)
Case "Others"
calcTotal(oth, total_value, t)
End Select
If total_value <= 0 Then Exit For
Next
Debug.Print("Supmat = " & supmat)
Debug.Print("Legal = " & legal)
Debug.Print("POL = " & pol)
Debug.Print("Others = " & oth)
End Sub
Private Sub calcTotal(ByRef subtotal As Decimal, ByRef total_value As Decimal, t As Decimal)
If total_value > t Then
subtotal += t
total_value -= t
Else
subtotal += total_value
total_value = 0
End If
End Sub

RunningSum inside another

I have a report with the following data
IdSource 20170629 20170628 20170626 20170625 20170624 20170623
Id1. OK KO N/A KO OK KO
I want to count the number of days my data (status of a workflow) is KO. N/A means the worflow is not expected, so it should not be counted.
Expected results :
IdSource 20170629 20170628 20170626 20170625 20170624 20170623
Id1. OK KO(2) N/A KO(1) OK KO(1)
The count must be reset at each OK.
In SQL, I would do
select t.*,
sum(case when status = 'KO' then 1 else 0 end) over (partition by id, cume_ko order by date) as nbDayKO
from (select t.*,
sum(case when status = 'OK' then 1 else 0 end) over (partition by id order by date) as cume_ko
from t
) t
I tried to use the RunningSum function without success:
I need to inverse the sort on the date
I cannot use the result of a runningSum inside another.
Thanks for your help
It's ugly and not very efficient, but I did not find any other solutions. Here is how I did it :
If ([status] = 0) Then 0
Else (
(If (RelativeValue([status];([dayOfWeek]);1) = 1) Then
If (RelativeValue([status];([dayOfWeek]);2) = 1) Then
If (RelativeValue([status];([dayOfWeek]);3) = 1) Then
If (RelativeValue([status];([dayOfWeek]);4) = 1) Then
If (RelativeValue([status];([dayOfWeek]);5) = 1) Then
If (RelativeValue([status];([dayOfWeek]);6) = 1) Then
If (RelativeValue([status];([dayOfWeek]);7) = 1) Then
If (RelativeValue([status];([dayOfWeek]);8) = 1) Then
If (RelativeValue([status];([dayOfWeek]);9) = 1) Then
If (RelativeValue([status];([dayOfWeek]);10) = 1) Then
If (RelativeValue([status];([dayOfWeek]);11) = 1) Then
If (RelativeValue([status];([dayOfWeek]);12) = 1) Then
If (RelativeValue([status];([dayOfWeek]);13) = 1) Then
If (RelativeValue([status];([dayOfWeek]);14) = 1) Then
If (RelativeValue([status];([dayOfWeek]);15) = 1) Then 15
Else 14
Else 13
Else 12
Else 11
Else 10
Else 9
Else 8
Else 7
Else 6
Else 5
Else 4
Else 3
Else 2
Else 1
Else 0)+[status])

Case statement and OR in SQL

Can someone please advise on the below? I have a number of fields which I would like to use and combine these to get the data in one column. I am using the following case statement but am not getting the results I expect.
CASE
WHEN m.u_hearing = 1 THEN 'Hearing'
WHEN m.u_learning_reading_diff = 1 THEN 'Learning or reading Difficulty'
WHEN m.u_long_term_ill = 1 THEN 'Long Term Illness'
WHEN m.u_mental_illness = 1 THEN 'Mental Illness'
WHEN m.u_mobility = 1 THEN 'Mobility'
WHEN m.u_physical_coordination = 1 THEN 'Physical Co-ordination'
WHEN m.u_physical_dis = 1 THEN 'Physical Disability'
WHEN m.u_red_physical_cap = 1 THEN 'Reduced_physical_capacity'
WHEN m.u_speech = 1 THEN 'Speech'
WHEN m.u_vision = 1 THEN 'Vision'
WHEN m.u_other_dis = 1 THEN 'Other_Disability'
WHEN (m.u_hearing = 1 AND (m.u_learning_reading_diff = 1 OR (m.u_speech = 1))) THEN 'Multiple'
It is the last statement that is not giving the result I would like as if there are multiple fields with Yes then I would like multiple returned but it seems it is picking the first case.
Put the "hardest" condition first
case WHEN m.u_hearing = 1 AND (m.u_learning_reading_diff = 1 OR m.u_speech = 1) THEN 'Multiple'
WHEN m.u_hearing = 1 THEN 'Hearing' ...
Because a case stops at the first condition that is true
When using CASE statements, they will function in the order you have specified.
So if m.u_Hearing = 1 then it will stop at the first line and not reach the bottom one.
This will work for what you require, however list it in the order you prefer.
CASE
WHEN (m.u_hearing = 1 AND (m.u_learning_reading_diff = 1 OR (m.u_speech = 1))) THEN 'Multiple'
WHEN m.u_hearing = 1 THEN 'Hearing'
WHEN m.u_learning_reading_diff = 1 THEN 'Learning or reading Difficulty'
WHEN m.u_long_term_ill = 1 THEN 'Long Term Illness'
WHEN m.u_mental_illness = 1 THEN 'Mental Illness'
WHEN m.u_mobility = 1 THEN 'Mobility'
WHEN m.u_physical_coordination = 1 THEN 'Physical Co-ordination'
WHEN m.u_physical_dis = 1 THEN 'Physical Disability'
WHEN m.u_red_physical_cap = 1 THEN 'Reduced_physical_capacity'
WHEN m.u_speech = 1 THEN 'Speech'
WHEN m.u_vision = 1 THEN 'Vision'
WHEN m.u_other_dis = 1 THEN 'Other_Disability'
From what I know you cannot use your first statement again in another "when" like your
WHEN m.u_hearing = 1 THEN 'Hearing'
Above condition try to use else if it is working and feasible for you in end.
Else 'Multiple'

how to do calculations with multiple check boxes in vb.net?

for example i have 5 check boxes and these check boxes are names of products with different prices which are constant and displayed in five text boxes when a certain check box is checked
and i also have 5 text boxes for the quantity which depends on the input of the user. now for example i only checked 2 check boxes and input their quantity let say product one = 100 and product 2 = to 200 and i input 2 for both of their quantity display the total amount in only one text box. how can i code it because when i use the if else statement, it only calculate and display the price of one product while i have chosen or checked 2 products and when i used or in the if statement, when i only checked 2 check boxes and input their quantities, i get an error which is format string unhandle. This is my code:
If chkPopcorn.Checked = True Then
quantity1 = Integer.Parse(txtQuantityPopcorn.Text)
price1 = txtPricePopcorn.Text * quantity1
ElseIf chkBurger.Checked = True Then
quantity2 = Integer.Parse(txtQuantityBurger.Text)
price2 = txtPriceBurger.Text * quantity2
ElseIf chkSpaghetti.Checked = True Then
quantity3 = Integer.Parse(txtQuantitySpaghetti.Text)
price3 = txtPriceSpaghetti.Text * quantity3
ElseIf chkHotdog.Checked = True Then
quantity4 = Integer.Parse(txtQuantityHotdog.Text)
price4 = txtPriceHotdog.Text * quantity4
ElseIf chkCupcake.Checked = True Then
quantity5 = Integer.Parse(txtQuantityCupcake.Text)
price5 = txtPriceCupcake.Text * quantity5
End If
End If
txtSales.Text = price1 + price2 + price3 + price4 + price5
Simple to fix, use 5 If statements in a row, instead of ElseIf
If chkPopcorn.Checked = True Then
quantity1 = Integer.Parse(txtQuantityPopcorn.Text)
price1 = txtPricePopcorn.Text * quantity1
End If
If chkBurger.Checked = True Then
quantity2 = Integer.Parse(txtQuantityBurger.Text)
price2 = txtPriceBurger.Text * quantity2
End If
If chkSpaghetti.Checked = True Then
quantity3 = Integer.Parse(txtQuantitySpaghetti.Text)
price3 = txtPriceSpaghetti.Text * quantity3
End If
If chkHotdog.Checked = True Then
quantity4 = Integer.Parse(txtQuantityHotdog.Text)
price4 = txtPriceHotdog.Text * quantity4
End If
If chkCupcake.Checked = True Then
quantity5 = Integer.Parse(txtQuantityCupcake.Text)
price5 = txtPriceCupcake.Text * quantity5
End If
txtSales.Text = price1 + price2 + price3 + price4 + price5
End Sub