I'm trying to figure out how many 'Open Quotes' there were in each month/year and not sure how to do this automatically. I don't want to have to manually enter time ranges to do this and looking for help.
I've uploaded a sample CSV file and data here:
https://drive.google.com/open?id=0B4xdnV0LFZI1N1kwbFUtOUpMa2c
The first two rows from the tables look like this:
tbl_QuoteWin
Quote_No Add_Date Update_Date Quote_Status
5 05-Aug-15 10-15-Oct Win
6 17-Sep-15 18-15-Nov Win
tbl_QuoteOpen
Quote_No Add_Date Update_Date Quote_Status
1 08-Aug-15 Open
3 07-Sep-15 Open
tbl_QuoteLoss
Quote_No Add_Date Update_Date Quote_Status
2 07-Aug-15 17-Oct-15 Loss
4 25-Sep-15 7-Nov-15 Loss
The desired output is a way for me to divide how many quotes we won in a month by how many quotes were open in a month. I don't know how to capture the months between 'Add_Date_Month' and 'Update_Date_Month'.
For example, in tbl_QuoteWin, quote #2 should be in the count of 'Open' quotes for Aug-2015 and Sept-2015 because this quote was in an 'Open' status before it was put in a 'Win' status in Oct-2015.
I originally tried to pull out just the month/year and then thought I might be able to do something with that but I really don't know how to tackle this problem. Even if I did a DATEDIFF() I'd get a length of time, not the actual months.
I hope this makes sense and thank you in advance for helping me or at least pointing me in the right direction.
Thank you!
SELECT MONTH(Add_Date),YEAR(Add_Date), COUNT(*)
FROM tbl_QUOTEOpen
GROUP BY MONTH(Add_Date),YEAR(Add_Date)
This solution is possible because only quotes with an open status are in the Open Quote table. Once they are won or lost, they move to another table.
The results, based on the tables in your question, would be
8 2015 1
9 2015 1
Related
I'm working on an MRP simulation in which I have to subtract demand or add supply qty to available stock and I hope you can be of support. Find below the result I want to achieve.
I have 1 value for stock = 22 and a lot of values for future demand/supply on specific dates.
Part
Stock
Demand/Supply qty
Demand/Supply Date
Result
1000680
22
-1
2023-01-01
21
1000680
21* what I want to achieve
-15
2023-01-02
6* expected outcome
1000680
6* what I want to achieve
+10
2023-01-03
16* expected outcome
I'm still on the SQL learning curve. I started to add rownumbers to the lines to make sure that the sequence is correct:
select
part,
rownum = ROW_NUMBER() OVER (ORDER BY part, mrp_due_date),
current_stock_qty,
demand_supply_qty,
current_stock - qty as new_stock_qty, -- if demand
current_stock + qty as new_stock_qty, -- if supply
mrp_due_date
from #base
Then I tried the lag function to derive previous row 'new_stock_qty' at date but this only worked for the first line (see image:
)
So I probably need the loop function to first calculate stock-demand and use the result as new stock.
I have looked through similar questions asked on this site, but I find it difficult to define my solution based on that information.
Ok, from the title it seems to be impossible to understand, I'll try to be as clear as possible.
Basically, I have a table, let's call it 'records'. In this table I have some products, of which I store 'id', 'codex' (which is a unique identifier for a certain product in the whole database), 'price' and 'situation'. This last one is a string which tells me wether the product has just entered the store (in that case it is set to 'IN'), or it has already been sold ('OUT' in this case).
The database was not created by us, I HAVE to work with that although it is horribly structured... The guy who originally projected the database decided to register when a product's situation passes from 'IN' to 'OUT' in the following way: instead of UPDATEing the corresponding value in the table, he used to take the row of data with 'IN' as situation, and to DUPLICATE it setting, that time, 'OUT' as situation.
Just to sum up: if a product has not been sold yet, it will have one row of dedicated data; otherwise those rows will be two, identical except for the 'situation' field.
What I need to do is: select a product if (and ONLY if) there is no duplicate for it. Basically, I can (and should) look for a 'codex', and if I my Count(codex) ends up being >1, I do not select the row.
I hope the explanation of the process is clear enough...
I tryed many alternative (no, SELECT DISTINCT is not a solution): des anyone have an idea of how to do that? Because really, none of us three could come up with a good solution!
Here is the schema for the table, I hope it is sufficiently clear, and if not do not hesitate asking for more details.
Just as a reminder: the project is in (sigh...) VB.net, the database is in Microsoft Access (mdb).
I could not find a solution on StackOverFlow, I hope this is not a duplicate question! Thanks in advance for the help.
id codex price situation
1 1 2.50 IN
2 1 2.50 OUT
3 2 3.45 IN
4 3 21.50 IN
5 2 3.45 OUT
6 4 1.50 IN
To check if I understand what your problem is... In your example table you just want to get the lines with ID 4 a 6, right?
If is that what you want, and If you want only the not sold ones try this command
SELECT
*
FROM
records
WHERE
codex
not in
(
SELECT
codex
FROM
records
WHERE
situation ='OUT'
)
Background
I have a database that hold records of all assets in an office. Each asset have a condition, a category name and an age.
A ConditionID can be;
In use
Spare
In Circulation
CategoryID are;
Phone
PC
Laptop
and Age is just a field called AquiredDate which holds records like;
2009-04-24 15:07:51.257
Example
I've created an example of the inputs of the query to explain better what I need if possible.
NB.
Inputs are in Orange in the above example.
I've split the example into two separate queries.
Count would be the output
Question
Is this type of query and result set possible using SQL alone? And if so where do I start? Would it be easier to use Ms Excel also?
Yes it is possible, for your orange fields you can just e.g.
where CategoryID ='Phone' and ConditionID in ('In use', 'In Circulation')
For the yellow one you could do a datediff of days of accuired date to now and divide it by 365 and floor that value, to get the last one (6+ years category) you need to take the minimum of 5 and the calculated value so you get 0 for all between 0-1 year old etc. until 5 which has everything above 6 years.
When you group by that calculated column and select the additional the count you get what you desire.
I want something strange here. I've table names as EMP_INFO which contains few details of an employee (i.e. Name,Designation, JOIN_FROM, JOIN_TO). I am trying to figure out term for each employee on yearly basis. I've below types of data
EMP_ID EMP_DESIG JOIN_FROM JOIN_TO Query Result
1 Supervisor 01-05-11 30-04-13 Should Display
2 Supervisor 15-06-10 31-12-12 Should Display
3 Jobar 01-01-12 31-12-13 Should Display
4 SR Superior 01-12-11 31-12-15 Should Display
5 Supervisor 01-05-11 31-12-13 Should Display
6 Supervisor 01-05-11 31-12-13 Should Display
7 Supervisor 01-05-11 31-12-13 Should Display
8 Supervisor 01-02-12 15-06-13 Should Display
9 SR Superior 16-03-10 18-11-11 Should Display
10 SR Superior 16-06-05 18-11-11 Should Display
11 Jobar 30-11-11 31-12-13 Should Display
12 Superior 02-02-05 31-12-20 Should Display
13 Jobar 30-11-11 31-12-13 Should Display
14 Jobar 30-11-09 31-12-10 Should Not Display
Basically what i need is I have date range in my report and let's say From: "01-Jun-11" To "31-Dec-13". From above record set report should retrieve all records as all records contains this both dates.
I have tried by using BETWEEN syntax but i believe it will not work.
If anyone can help me in this than it would be appreciated.
Thanks in Advance.. And one more thing if this details is not enough to understand than let me know i will add more in details.
Modified
Query which I tried
SELECT EI.*
FROM EMP_INFO EI,
(SELECT
TO_DATE('01-JUN-2011','DD-MON-YYYY') A,
TO_DATE('31-DEC-2013','DD-MON-YYYY') B FROM DUAL) X
WHERE
(EI.JOIN_FROM IS NOT NULL AND EI.JOIN_TO IS NOT NULL)
AND (
X.A BETWEEN EI.JOIN_FROM AND EI.JOIN_TO
AND X.B BETWEEN EI.JOIN_FROM AND EI.JOIN_TO
OR (EI.JOIN_FROM >= X.B AND EI.JOIN_TO <=X.A) )
Modified Added column (Query Result) on above table which contains result for each record.
So you simply want all records where the join time is in the given time range? That would be:
SELECT *
FROM EMP_INFO
WHERE JOIN_FROM BETWEEN
TO_DATE('01-JUN-2011','DD-MON-YYYY', 'NLS_DATE_LANGUAGE=AMERICAN') AND
TO_DATE('31-DEC-2013','DD-MON-YYYY', 'NLS_DATE_LANGUAGE=AMERICAN')
AND JOIN_TO BETWEEN
TO_DATE('01-JUN-2011','DD-MON-YYYY', 'NLS_DATE_LANGUAGE=AMERICAN') AND
TO_DATE('31-DEC-2013','DD-MON-YYYY', 'NLS_DATE_LANGUAGE=AMERICAN');
EDIT: Sorry, I got it now. You are looking for all time ranges that overlap with the given range. That would be: ranges that start before and end within, ranges that start before and end after, ranges that start within and end within and ranges that start within and end after. Another way to express this is: Either the given time range start is within the other time range or the other time range start is within the given time range. Here is the according statement:
SELECT *
FROM EMP_INFO
WHERE JOIN_FROM BETWEEN
TO_DATE('01-JUN-2011','DD-MON-YYYY', 'NLS_DATE_LANGUAGE=AMERICAN') AND
TO_DATE('31-DEC-2013','DD-MON-YYYY', 'NLS_DATE_LANGUAGE=AMERICAN')
OR TO_DATE('01-JUN-2011','DD-MON-YYYY', 'NLS_DATE_LANGUAGE=AMERICAN')
BETWEEN JOIN_FROM AND JOIN_TO;
And here is the SQL fiddle: http://sqlfiddle.com/#!4/b58b3/3
Convert to same format and compare. There may be a time component in the dates stored in database. Previous answer was wrong.
The problem that I have is SQL Server Reporting Services does not like Sum(First()) notation. It will only allow either Sum() or First().
The Context
I am creating a reconciliation report. ie. what sock we had a the start of a period, what was ordered and what stock we had at the end.
Dataset returns something like
Type,Product,Customer,Stock at Start(SAS), Ordered Qty, Stock At End (SAE)
Export,1,1,100,5,90
Export,1,2,100,5,90
Domestic,2,1,200,10,150
Domestic,2,2,200,20,150
Domestic,2,3,200,30,150
I group by Type, then Product and list the customers that bought that product.
I want to display the total for SAS, Ordered Qty, and SAE but if I do a Sum on the SAS or SAE I get a value of 200 and 600 for Product 1 and 2 respectively when it should have been 100 and 200 respectively.
I thought that i could do a Sum(First()) But SSRS complains that I can not have an aggregate within an aggregate.
Ideally SSRS needs a Sum(Distinct())
Solutions So Far
1. Don't show the Stock at Start and Stock At End as part of the totals.
2. Write some code directly in the report to do the calc. tried this one - didn't work as I expected.
3. Write an assembly to do the calculation. (Have not tried this one)
Edit - Problem clarification
The problem stems from the fact that this is actually two reports merged into one (as I see it). A Production Report and a sales report.
The report tried to address these criteria
the market that we sold it to (export, domestic)
how much did we have in stock,
how much was produced,
how much was sold,
who did we sell it to,
how much do we have left over.
The complicating factor is the who did we sell it to. with out that, it would have been relativly easy. But including it means that the other top line figures (stock at start and stock at end) have nothing to do with the what is sold, other than the particular product.
I had a similar issue and ended up using ROW_NUMBER in my query to provide a integer for the row value and then using SUM(IIF(myRowNumber = 1, myValue, 0)).
I'll edit this when I get to work and provide more data, but thought this might be enough to get you started. I'm curious about Adolf's solution too.
Pooh! Where's my peg?!
Have you thought about using windowing/ranking functions in the SQL for this?
This allows you to aggregate data without losing detail
e.g. Imagine for a range of values, you want the Min and Max returning, but you also wish to return the initial data (no summary of data).
Group Value Min Max
A 3 2 9
A 7 2 9
A 9 2 9
A 2 2 9
B 5 5 7
B 7 5 7
C etc..
Syntax looks odd but its just
AggregateFunctionYouWant OVER (WhatYouWantItGroupedBy, WhatYouWantItOrderedBy) as AggVal
Windowing
Ranking
you're dataset is a little weird but i think i understand where you're going.
try making the dataset return in this order:
Type, Product, SAS, SAE, Customer, Ordered Qty
what i would do is create a report with a table control. i would set up the type, product, and customer as three separate groups. i would put the sas and sae data on the same group as the product, and the quantity on the customer group. this should resemble what i believe you are trying to go for. your sas and sae should be in a first()
Write a subquery.
Ideally SSRS needs a Sum(Distinct())
Re-write your query to do this correctly.
I suspect your problem is that you're written a query that gets you the wrong results, or you have poorly designed tables. Without knowing more about what you're trying to do, I can't tell you how to fix it, but it has a bad "smell".