How can I combine these two query from the same table? - sql

Since "ColdFusion does not support joins through INNER JOIN or OUTER JOIN clauses"
How would I be able to combine these two queries, where they give me data from
the past 2 months?
select starburst_dept_name, starburst_dept_average,MONTHLY_PAST_DATE
from cse_reports_month
where starburst_dept_name is not NULL
and YEAR(MONTHLY_PAST_DATE) = YEAR(GETDATE())
and MONTH(MONTHLY_PAST_DATE) = MONTH(GETDATE())-1
select starburst_dept_name, starburst_dept_average,MONTHLY_PAST_DATE
from cse_reports_month
where starburst_dept_name is not NULL
and YEAR(MONTHLY_PAST_DATE) = YEAR(GETDATE())
and MONTH(MONTHLY_PAST_DATE) = MONTH(GETDATE())-2
I would like a query to combine these two how would I do this so it would
work in ColdFusion?
What I would like to to is compare the starburst_dept_average last month > starburst_dept_average last 2 month ago?

Just to clarify, CF does not support INNER AND OUTER JOINs only in a query of a query (QoQ). Is cse_reports_month the name of a query or the name of a database table? Your use of getdate() makes it sound like this is a regular SQL query, not a QoQ.
The following query should work according to your original logic:
SELECT starburst_dept_name, starburst_dept_average, MONTHLY_PAST_DATE
FROM cse_reports_month
WHERE starburst_dept_name is not NULL
AND YEAR(MONTHLY_PAST_DATE) = YEAR(GETDATE())
AND (
MONTH(MONTHLY_PAST_DATE) = MONTH(GETDATE())-1 OR
MONTH(MONTHLY_PAST_DATE) = MONTH(GETDATE())-2
)
But as was pointed out, this won't work for Jan. & Feb.- you'll need to use some different date comparison operators.
Depending on exactly what you are trying to show (and what the MONTHLY_PAST_DATE data represents), the following may work (you may need to modify a bit according your specific needs):
SELECT starburst_dept_name, starburst_dept_average, MONTHLY_PAST_DATE
FROM cse_reports_month
WHERE starburst_dept_name is not NULL
AND DATEDIFF(m,MONTHLY_PAST_DATE,getdate()) IN (1,2)

You can combine these query results by using the SQL UNION statement.
http://www.w3schools.com/sql/sql_union.asp

Related

get the latest records

I am currently still on my SQL educational journey and need some help!
The query I have is as below;
SELECT
Audit_Non_Conformance_Records.kf_ID_Client_Reference_Number,
Audit_Non_Conformance_Records.TimeStamp_Creation,
Audit_Non_Conformance_Records.Clause,
Audit_Non_Conformance_Records.NC_type,
Audit_Non_Conformance_Records.NC_Rect_Received,
Audit_Non_Conformance_Records.Audit_Num
FROM Audit_Non_Conformance_Records
I am trying to tweak this to show only the most recent results based on Audit_Non_Conformance_Records.TimeStamp_Creation
I have tried using MAX() but all this does is shows the latest date for all records.
basically the results of the above give me this;
But I only need the result with the date 02/10/2019 as this is the latest result. There may be multiple results however. So for example if 02/10/2019 had never happened I would need all of the idividual recirds from the 14/10/2019 ones.
Does that make any sense at all?
You can filter with a subquery:
SELECT
kf_ID_Client_Reference_Number,
TimeStamp_Creation,
Clause,
NC_type,
NC_Rect_Received,
Audit_Num
FROM Audit_Non_Conformance_Records a
where TimeStamp_Creation = (
select max(TimeStamp_Creation)
from Audit_Non_Conformance_Records
)
This will give you all whose TimeStamp_Creation is equal to the greater value available in the table.
If you want all records that have the greatest day (exluding time), then you can do:
SELECT
kf_ID_Client_Reference_Number,
TimeStamp_Creation,
Clause,
NC_type,
NC_Rect_Received,
Audit_Num
FROM Audit_Non_Conformance_Records a
where cast(TimeStamp_Creation as date) = (
select cast(max(TimeStamp_Creation) as date)
from Audit_Non_Conformance_Records
)
Edit
If you want the latest record per refNumber, then you can correlate the subquery, like so:
SELECT
kf_ID_Client_Reference_Number,
TimeStamp_Creation,
Clause,
NC_type,
NC_Rect_Received,
Audit_Num
FROM Audit_Non_Conformance_Records a
where TimeStamp_Creation = (
select max(TimeStamp_Creation)
from Audit_Non_Conformance_Records a1
where a1.refNumber = a.refNumber
)
For performance, you want an index on (refNumber, TimeStamp_Creation).
If you want the latest date in SQL Server, you can express this as:
SELECT TOP (1) WITH TIES ancr.kf_ID_Client_Reference_Number,
ancr.TimeStamp_Creation,
ancr.Clause,
ancr.NC_type,
ancr.NC_Rect_Received,
ancr.Audit_Num
FROM Audit_Non_Conformance_Records ancr
ORDER BY CONVERT(date, ancr.TimeStamp_Creation) DESC;
SQL Server is pretty good about handling dates with conversions, so I would not be surprised if this used an index on TimeStamp_Creation.

Joining multiple tables returning duplicates

I am trying the following select statement including columns from 4 tables. But the results return each row 4 times, im sure this is because i have multiple left joins but i have tried other joins and cannot get the desired result.
select table1.empid,table2.name,table2.datefrom, table2.UserDefNumber1, table3.UserDefNumber1, table4.UserDefChar6
from table1
inner join table2
on table2.empid=table1.empid
inner join table3
on table3.empid=table1.empid
inner join table4
on table4.empid=table1.empid
where MONTH(table2.datefrom) = Month (Getdate())
I need this to return the data without any duplicates so only 1 row for each entry.
I would also like the "where Month" clause at the end look at the previous month not the current month but struggling with that also.
I am a bit new to this so i hope it makes sense.
Thanks
If the duplicate rows are identical on each column you can use the DISTINCT keyword to eliminate those duplicates.
But I think you should reconsider your JOIN or WHERE clause, because there has to be a reason for those duplicates:
The WHERE clause hits several rows in table2 having the same month on a single empid
There are several rows with the same empid in one of the other tables
both of the above is true
You may want to rule those duplicate rows out by conditions in WHERE/JOIN instead of the DISTINCT keyword as there may be unexpected behaviour when some data is changing in a single row of the original resultset. Then you start having duplicate empids again.
You can check if a date is in the previous month by following clause:
date BETWEEN dateadd(mm, -1, datefromparts(year(getdate()), month(getdate()), 1))
AND datefromparts(year(getdate()), month(getdate()), 1)
This statment uses DATEFROMPARTS to create the beginning of the current month twice, subtract a month from the first one by using DATEADD (results in the beginning of the previous month) and checks if date is between those dates using BETWEEN.
If your query is returning duplicates, then one or more of the tables have duplicate empid values. This is a data problem. You can find them with queries like this:
select empid, count(*)
from table1
group by empid
having count(*) > 1;
You should really fix the data and query so it returns what you want. You can do a bandage solution with select distinct, but I would not usually recommend that. Something is causing the duplicates, and if you do not understand why, then the query may not be returning the results you expect.
As for your where clause. Given your logic, the proper way to express this would include the year:
where year(table2.datefrom) = year(getdate()) and
month(table2.datefrom) = month(Getdate())
Although there are other ways to express this logic that are more compatible with indexes, you can continue down this course with:
where year(table2.datefrom) * 12 + month(table2.datefrom) = year(getdate()) * 12 + Month(Getdate()) - 1
That is, convert the months to a number of months since time zero and then use month arithmetic.
If you care about indexes, then your current where clause would look like:
where table2.datefrom >= dateadd(day,
- (day(getdate) - 1),
cast(getdate() as date) and
table2.datefrom < dateadd(day,
- (dateadd(month, 1, getdate()) - 1),
cast(dateadd(month, 1, getdate()) as date)
Eliminate duplicates from your query by including the distinct keyword immediately after select
Comparing against a previous month is slightly more complicated. It depends what you mean:
If the report was run on the 23rd Jan 2015, would you want 01/12/2014-31/12/2014 or 23/12/2014-22/01/2015?

T-SQL Group By and Sub Query

I am aware of what the problem is with my query, but am really struggling to find a solution here.
SQL Fiddle
I guess I'm not even really sure how to ask this. What I'm trying to achieve sum all tracking numbers for a date range grouped by branch, but (and this is the kicker) include any other records in the sum that have the same tracking number. I thought of doing something like this, but of course SQL Server doesn't like this because I can't have a subquery in an aggregate function.
MAX((select SUM(demo.NegotiatedRate) where #demo.Tracking = demo2.Tracking)) as NegotiatedRate
Here is the query I have so far if anyone doesnt want to click the SQL Fiddle link
select demo.Branch,
SUM(demo.NegotiatedRate) as NegotiatedRate,
SUM(demo2.BillRate) as BillRate
from demo
join demo2 on demo2.Tracking = demo.Tracking
where demo.ShipDate = '2014-05-01'
group by demo.Branch
Expected Output
The output that I am trying to achieve would look something like this. The GH6 negotiated rate and bill rate should match even though one of the GH6 entries falls outside of desired date range.
Branch NegotiatedRate BillRate
GH4 50 50
GH6 25 25
You can pre-project the overall (non date-range bound, unfiltered) totals in a separate derived table or cte and then join back to it:
WITH totals AS
(
SELECT demo.Tracking,
SUM(demo.NegotiatedRate) as NegotiatedRate
from demo
group by demo.Tracking
)
select demo.Branch,
MIN(totals.NegotiatedRate) as NegotiatedRate,
SUM(demo2.BillRate) as BillRate
from demo
join demo2 on demo2.Tracking = demo.Tracking
join totals on totals.Tracking = demo.Tracking
where demo.ShipDate = '2014-05-01'
group by demo.Branch;
SqlFiddle here
Given that there should only be one NegotiatedRate per tracking, you can circumvent the need to add the summed totals.NegotiatedRate to the outer query by applying an aggregate (I've used MIN), although this is just to pacify Sql.
As a bit of a simpler answer, you can do something like:
SELECT demo.Branch,
SUM(demo.NegotiatedRate) AS NegotiatedRate,
demo2.BillRate
FROM demo
JOIN demo2 on demo2.Tracking = demo.Tracking
WHERE demo.Tracking IN
(
SELECT Tracking
FROM demo
WHERE ShipDate = '2014-05-01'
)
GROUP BY demo.Branch, demo2.BillRate
As I understand it, you get all the tracking numbers you want in a certain date range, then get all the information from those tracking numbers, no matter the date range. Then groups them by the Branch and BillRate, both of which should be one value for each tracking number.
If I understand correctly, you want to include all rows when one of the dates is the selected date. If this is correct, then you want the logic in the having clause, not in the where clause:
select demo.Branch,
SUM(demo.NegotiatedRate) as NegotiatedRate,
SUM(demo2.BillRate) as BillRate
from demo
join demo2 on demo2.Tracking = demo.Tracking
group by demo.Branch
having sum(case when demo.ShipDate = '2014-05-01' then 1 else 0 end) > 0

Subtracting 2 values from a query and sub-query using CROSS JOIN in SQL

I have a question that I'm having trouble answering.
Find out what is the difference in number of invoices and total of invoiced products between May and June.
One way of doing it is to use sub-queries: one for June and the other one for May, and to subtract the results of the two queries. Since each of the two subqueries will return one row you can (should) use CROSS JOIN, which does not require the "on" clause since you join "all" the rows from one table (i.e. subquery) to all the rows from the other one.
To find the month of a certain date, you can use MONTH function.
Here is the Erwin document
This is what I got so far. I have no idea how to use CROSS JOIN in this situation
select COUNT(*) TotalInv, SUM(ILP.ProductCount) TotalInvoicedProducts
from Invoice I, (select Count(distinct ProductId) ProductCount from InvoiceLine) AS ILP
where MONTH(inv_date) = 5
select COUNT(*) TotalInv, SUM(ILP.ProductCount) TotalInvoicedProducts
from Invoice I, (select Count(distinct ProductId) ProductCount from InvoiceLine) AS ILP
where MONTH(inv_date) = 6
If you guys can help that would be great.
Thanks
The problem statement suggests you use the following steps:
Construct a query, with a single result row giving the values for June.
Construct a query, with a single result row giving the values for May.
Compare the results of the two queries.
The issue is that, in SQL, it's not super easy to do that third step. One way to do it is by doing a cross join, which yields a row containing all the values from both subqueries; it's then easy to use SELECT (b - a) ... to get the differences you're looking for. This isn't the only way to do the third step, but what you have definitely doesn't work.
can't you do something with subqueries? I haven't tested this, but something like the below should give you 4 columns, invoices and products for may and june.
select (
select 'stuff' a, count(*) as june_invoices, sum(products) as products from invoices
where month = 'june'
) june , (
select 'stuff' a, count(*) as may_invoices, sum(products) as products from invoices
where month = 'may'
) may
where june.a = may.a

Using DATEPART function in access SQL query with joined tables and aggregate function

I want to select the year and quarter parts of the date in a table rather than the whole date. I built the following query to achieve this:
SELECT Clients.ClientID,
Sum(AccountVals.ValuationAmount) AS SumOfValuationAmount,
Datepart("YYYY", AccountVals.valuationAmount) AS valYear,
Datepart("Q", AccountVals.valuationAmount) AS valQuarter
FROM (Accounts
INNER JOIN Clients
ON Accounts.ClientID = Clients.ClientID)
INNER JOIN AccountVals
ON Accounts.AccountID = AccountVals.AccountID
GROUP BY Clients.ClientID,
SumOfValuationAmount,
valYear,
valQuarter;
Although I have successfully used DATEPART in a simple select query the fact that this query is both an aggregate function and have linked tables is throwing me. Any ideas?
EDIT: I realise my query doesn't have any criteria which means it could be trying to aggregate the result from different dates so it can't show the dateparts. I tried adding something like HAVING valYear = 2012 AND valQuarter = 3 but get the same error
I don't think you can use an alias in the group by clause, at least not without a subquery. One solution is to repeat the exact expression in the group by, f.e.:
group by
Clients.ClientID
, datepart("YYYY", AccountVals.valuationAmount)
, datepart("Q", AccountVals.valuationAmount)