Before we start, I apologize for my MYSQL novice status. I'm trying to self-teach and struggling a bit with basic the basic structure.
Background on my question: Consider a company that issues bills once a quarter... and roughly two months after the end of the last quarter. I have a table (Quarter_Identify) that has several columns:
Quarter_Start EX: 01-01-2010
Quarter_End EX: 03-31-2010
Quarter_Ident EX: 1000 <--- iterating number for each quarter (next
quarter will be 1001)
Date_Billed This is the field I'm trying to populate from another table
The other table (Billing_List_1) contains:
Date_Billed EX: 05-23-2010
Lots of other nonsense related to the customers
We take all the orders during the quarter, and bill about 60 days after it ends. So, in the example above, the 5-23-2010 billing would be related to the Jan - Mar quarter (we bill really late). I would like to take this date and populate it back as the Date_Billed associated with Quart_Ident "1000".
I'm fairly close and from my research I think I'm running into the issue that my "Where" clause includes a reference to the as-yet not created table "Skyline". The "skyline" table gets everything together, but is essentially off by a month (I gave up trying to figure out the DateDiff function). So, I use the bottom piece to offset the result by one and get the right answer... except that it tells me I have an unknown column in my where clause (error 1054) the issue.
Select * from
(select Billing_List_1.date_billed, quarter_identify.quarter_start,
quarter_identify.quarter_end, quarter_identify.quarter_ident from Billing_List_1
join quarter_identify
on Billing_List_1.date_billed > quarter_identify.quarter_start
and Billing_list_1.date_billed < quarter_identify.quarter_end)
as SKYLINETABLE;
update quarter_identify A
set A.date_Billed = SKYLINETABLE.date_Billed
where A.quarter_ident = SKYLINETABLE.quarter_ident - 1
Any thoughts would be much appreciated. Have a great evening all.
Solution per TEEZ: Thanks again for the great help.
update quarter_identify A Left join
(Select * from
(select Billing_List_1.date_billed,
quarter_identify.quarter_start,
quarter_identify.quarter_end,
quarter_identify.quarter_ident from billing_list_1
join quarter_identify
on Billing_list_1.date_billed > quarter_identify.quarter_start
and Billing_list_1.date_billed < quarter_identify.quarter_end)
as T)
as SKYLINETABLE on 1
set A.date_billed = SKYLINETABLE.date_billed
where A.quarter_ident = SKYLINETABLE.quarter_ident - 1
I think you are wrong. what is SKYLINE table in update query?
You are joining tables in update query but table is not specified. you should use your first query in join with update query.
you need to use join SKYLINETABLE in join with your update query.
Like below:
update quarter_identify A left join (Select * from
(select Billing_List_1.date_billed, quarter_identify.quarter_start,
quarter_identify.quarter_end, quarter_identify.quarter_ident from Billing_List_1
join quarter_identify
on Billing_List_1.date_billed > quarter_identify.quarter_start
and Billing_list_1.date_billed < quarter_identify.quarter_end)) as SKYLINETABLE on[... specify on condition....]
set A.date_Billed = SKYLINETABLE.date_Billed
where A.quarter_ident = SKYLINETABLE.quarter_ident - 1
Please do required changes
Related
I am trying to calculate the moving average of my data. I have googled and found many examples on this site and others but am still stumped. I need to calculate the average of the previous 5 flow for the record selected for the specific product.
My Table looks like the following:
TMDT Prod Flow
8/21/2017 12:01:00 AM A 100
8/20/2017 11:30:45 PM A 150
8/20/2017 10:00:15 PM A 200
8/19/2017 5:00:00 AM B 600
8/17/2017 12:00:00 AM A 300
8/16/2017 11:00:00 AM A 200
8/15/2017 10:00:31 AM A 50
I have been trying the following query:
SELECT b.TMDT, b.Flow, (SELECT AVG(Flow) as MovingAVG
FROM(SELECT TOP 5 *
FROM [mytable] a
WHERE Prod="A" AND [a.TMDT]< b.TMDT
ORDER BY a.TMDT DESC))
FROM mytable AS b;
When I try to run this query I get an input prompt for b.TMDT. Why is b.TMDT not being pulled from mytable?
Should I be using a different method altogether to calculate my moving averages?
I would like to add that I started with another method that works but is extremely slow. It runs fast enough for tables with 100 records or less. However, if the table has more than 100 records it feels like the query comes to a screeching halt.
Original method below.
I created two queries for each product code (There are 15 products): Q_ProdA_Rank and Q_ProdA_MovAvg
Q_ProdA_RanK (T_ProdA is a table with Product A's information):
SELECT a.TMDT, a.Flow, (Select count(*) from [T_ProdA]
where TMDT<=a.TMDT) AS Rank
FROM [T_ProdA] AS a
ORDER BY a.TMDT DESC;
Q_ProdA_MovAvg
SELECT b.TMDT, b.Flow, Round((Select sum(Flow) from [Q_PRodA_Rank] where
Rank between b.Rank-1 and (b.Rank-5))/IIf([Rank]<5,Rank-1,5),0) AS
MovingAvg
FROM [Q_ProdA_Rank] AS b;
The problem is that you're using a nested subquery, and as far as I know (can't find the right site for the documentation at the moment), variable scope in subqueries is limited to the direct parent of the subquery. This means that for your nested query, b.TMDT is outside of the variable scope.
Edit: As this is an interesting problem, and a properly-asked question, here is the full SQL answer. It's somewhat more complex than your try, but should run more efficiently
It contains a nested subquery that first lists the 5 previous flows for per TMDT and prod, then averages that, and then joins that in with the actual query.
SELECT A.TMDT, A.Prod, B.MovingAverage
FROM MyTable AS A LEFT JOIN (
SELECT JoinKeys.TMDT, JoinKeys.Prod, Avg(Top5.Flow) As MovingAverage
FROM (
SELECT JoinKeys.TMDT, JoinKeys.Prod, Top5.Flow
FROM MyTable As JoinKeys INNER JOIN MyTable AS Top5 ON JoinKeys.Prod = Top5.Prod
WHERE Top5.TMDT In (
SELECT TOP 5 A.TMDT FROM MyTable As A WHERE JoinKeys.Prod = A.Prod AND A.TMDT < JoinKeys.TMDT ORDER BY A.TMDT
)
)
GROUP BY JoinKeys.TMDT, JoinKeys.Prod
) AS B
ON A.Prod = B.JoinKeys.Prod AND A.TMDT = B.JoinKeys.TMDT
While in my previous version I advocated a VBA approach, this is probably more efficient, only more difficult to write and adjust.
I have a MYSQL database that has two tables.
The first one called movies_interaction with the following parameters: movie_id, watcher_id, movie_duration.
the second table is movies_additional with the following parameters: movie_id and movie_length
What I need is to connect these two tables by which I need to retrieve the movies which was watched more than once AND more than 60% of its duration for each user.
This is so far what I wrote, but I know its wrong, so don't take that on me please.
SELECT watcher_id, COUNT(*)
AS video_count FROM movie_interaction
GROUP BY movie_id HAVING COUNT(*) >= 2 AND
movies_interaction.movie_duration *100 / movies_additional.movie_length >= 60
the fourth line of the code is where I need help!
Result can look like this: watcher_id1 = 9, watcher_id2 = 13...etc.
Thank you very much.
I'm not exactly sure on you need but I think that way look like that.
SELECT A.movie_id, COUNT(I.watcher_id) AS video_count
FROM movie_interaction I
INNER JOIN movie_additional A ON A.movie_id = I.movie_id AND
I.movie_duration / A.movie_length >= 0.60
GROUP BY A.movie_id
HAVING COUNT(I.watcher_id) >= 2
This will give you a list of movies watched more than one time for more that 60>%
There's a lot of these issues floating around the net with many solutions, but I'm really struggling with this one.
I have a table [BaseHrs] which looks a little like this -
p_ID b_Person WeekNos HrsRequired
1 A 2016-39 10
1 A 2016-40 10
1 A 2016-41 10
1 A 2016-42 10
1 B 2016-39 11
1 B 2016-40 11
1 B 2016-41 12
1 B 2016-42 09
The table continues with different p_ID, people & week numbers. There is no Primary Key and no indexing. This table also has no relationship with any other table.
It is populated from a Query connected to another table as well as a form for the [HrsRequired] field.
Scenario -
Project 1 (p_ID=1) has now been brought forward by two weeks and BaseHrs table no longer needs row for [WeekNos] 2016-41 & 2016-42.
I initially use a query to show which weeks the project is now running on (qry_SelectNewDates).
I have started my delete query by first creating a Select query which looks like this -
SELECT BaseHrs.*
FROM BaseHrs
LEFT JOIN qry_SelectNewDates
ON BaseHrs.WeekNos = qry_SelectNewDates.WeekNos
WHERE (((BaseHrs.p_ID)=[Forms]![frm_Projects]![p_ID])
AND ((BaseHrs.WeekNos) Not In ([qry_SelectNewDates].[WeekNos])));
This works as intended.
Converting that into a delete query produces an error though. Delete Query -
DELETE BaseHrs.*, BaseHrs.p_ID, BaseHrs.WeekNos
FROM BaseHrs
LEFT JOIN qry_SelectNewDates
ON BaseHrs.WeekNos = qry_SelectNewDates.WeekNos
WHERE (((BaseHrs.p_ID)=[Forms]![frm_Projects]![p_ID])
AND ((BaseHrs.WeekNos) Not In ([qry_SelectNewDates].[WeekNos])));
Error message -
Could not delete from specified tables.
I realise that there is often an issue when trying to delete records in this way. I've tried using it with just 'DELETE.*' in the first line without luck.
I have also made an attempt at a nested Query, but I just can't figure out how to construct it. Any guidance?
**********EDIT**********
With advice from #SunKnight0 I have added a primary key to my BaseHrs table and got this query -
DELETE *
FROM BaseHrs
WHERE b_pKey IN
(SELECT BaseHrs.b_pKey
FROM BaseHrs
LEFT JOIN qry_SelectNewDates
ON (BaseHrs.WeekNos = qry_SelectNewDates.WeekNos)
WHERE (((BaseHrs.p_ID)=[Forms]![frm_Projects]![p_ID])
AND ((BaseHrs.WeekNos) Not In ([qry_SelectNewDates].[WeekNos]))));
This query appears to work but takes a huge amount of time to run. Is that as good as it gets?
When I make this sql statement I get 6 of the same record returned. So if I expect to get 2 records returned, I get six of each record back so that is 12 in total.
SELECT
ce2.*
FROM customerentry ce, customerentrytrace cet, customerentry ce2
WHERE ce.accountid = 1
AND ce.companyid = 1
AND ce.accountid=cet.accountid
AND ce.accountid=ce2.accountid
AND ce.companyid=cet.companyid
AND ce.companyid=ce2.companyid
AND cet.documentno = '2012Faktura1'
AND cet.documenttype = 1
AND ce2.documentno = cet.offsetdocumentno
AND ce2.documenttype = cet.offsetdocumenttype
ORDER BY created;
I know that I can solve it by adding distinct, but I would like to know why I get 6 of the same record returned. Anyone who can help me?
Since we have no idea about your table structure probably there are some columns that are related 1 to n items and you haven't handled them in the WHERE section of your query.
As an extra measure you can focus on your data needs and add a GROUP BY section before your ORDER section.
You are using an INNER JOIN, so for example there are two entries in table cet matching your where clause for combining table ce and cet, giving you 2 entries/entry of table ce.
Thinking this further you can see that if there are 3 entries in table ce2 matching the where clause for combining table cet and ce2 you get 3 entries/entry of table cet.
Which makes 6 entries per entry of table ce in total, giving you 12 entries in total even if you have only 2 entries in table ce.
So think again about what join could be the right for your desired solution.
Here a link for some more explanation: Short explanation of joins
Problem might be because you have not properly joined tables. Please read about JOIN
SELECT ce2.*
FROM customerentry ce INNER JOIN customerentrytrace cet ON ce.accountid=cet.accountid AND ce.companyid=cet.companyid,
INNER JOIN customerentry ce2 ON ce.accountid=ce2.accountid AND ce.companyid=ce2.companyid AND ce2.documentno = cet.offsetdocumentno AND ce2.documenttype = cet.offsetdocumenttype
WHERE ce.accountid = 1
AND ce.companyid = 1
AND cet.documentno = '2012Faktura1'
AND cet.documenttype = 1
ORDER BY created;
I have a table "audit" with a "description" column, a "record_id" column and a "record_date" column. I want to select only those records where the description matches one of two possible strings (say, LIKE "NEW%" OR LIKE "ARCH%") where the record_id in each of those two matches each other. I then need to calculate the difference in days between the record_date of each other.
For instance, my table may contain:
id description record_id record_date
1 New Sub 1000 04/14/13
2 Mod 1000 04/14/13
3 Archived 1000 04/15/13
4 New Sub 1001 04/13/13
I would want to select only rows 1 and 3 and then calculate the number of days between 4/15 and 4/14 to determine how long it took to go from New to Archived for that record (1000). Both a New and an Archived entry must be present for any record for it to be counted (I don't care about ones that haven't been archived). Does this make sense and is it possible to calculate this in a SQL query? I don't know much beyond basic SQL.
I am using MySQL Workbench to do this.
The following is untested, but it should work asuming that any given record_id can only show up once with "New Sub" and "Archived"
select n.id as new_id
,a.id as archive_id
,record_id
,n.record_date as new_date
,a.record_date as archive_date
,DateDiff(a.record_date, n.record_date) as days_between
from audit n
join audit a using(record_id)
where n.description = 'New Sub'
and a.description = 'Archieved';
I changed from OR to AND, because I thought you wanted only the nr of days between records that was actually archived.
My test was in SQL Server so the syntax might need to be tweaked slightly for your (especially the DATEDIFF function) but you can select from the same table twice, one side grabbing the 'new' and one grabbing the 'archived' then linking them by record_id...
SELECT
newsub.id,
newsub.description,
newsub.record_date,
arc.id,
arc.description,
arc.record_date,
DATEDIFF(day, newsub.record_date, arc.record_date) AS DaysBetween
FROM
foo1 arc
, foo1 newsub
WHERE
(newsub.description LIKE 'NEW%')
AND
(arc.description LIKE 'ARC%')
AND
(newsub.record_id = arc.record_id)