Displaying weekly sales by day per branch mysql - php

I have 2 tables.
Table 1 = branch
containing
branch_id
branch_name
Table 2 = sales_data
containing
sales_id
sales_date
sales_branch
sales_profit
I need away of showing the total daily sales and total daily profit for each branch. I know how to bring back the result for a given week etc I am just really struggling on how to pull back the data.
I also need all the branches to be shown at all time and if they haven't sold anything to display a 0.
I have put together a quick image (http://i37.photobucket.com/albums/e71/dannyflap/screen_shot.jpg) of how I would like the finished. This is really driving me nuts :(
UPDATE
select sales_branch, WEEKDAY(sales_date), COUNT(sales_profit), SUM(sales_profit)
FROM sales_date
GROUP BY sales_branch, WEEKDAY(sales_date)
This then brings back the following example. Figures are made up.
sales_branch, day, units, profit:
| branch1 | 0 (as day) | 16 | 439 |
| branch1 | 1 (as day) | 12 | 651 |
| branch1 | 2 (as day) | 22 | 312 |
| branch1 | 3 (as day) | 61 | 614 |
| branch1 | 4 (as day) | 12 | 541 |
| branch1 | 5 (as day) | 24 | 102 |
| branch1 | 6 (as day) | 21 | 145 |

I guess you would have to do an outer join on table 1's branch_id and table 2's sales_branch and loop through the result to produce the table. With an outer join those branches who haven't sold anything will get a NULL, I think.
Is it the table generating you're having problem with? I don't think it's wise to do some spectacular SQL for this problem. My two cents.

You're going to need a foreign key in sales_data that maps to branch.
assuming sales_branch is something different than branch_name or branch_id, sales_data should contain:
sales_id sales_date sales_branch branch_id sales_profit
Also - you should post your code for getting back the result for a given week and we can help you build on that rather than give you the entire answer.
EDIT
Ok with modifying your sales_data table to have a foreign key branch_id to the branch table, this query should get you closer to what you're looking for.
SELECT b.branch_name, WEEKDAY(s.sales_date), COUNT(s.sales_profit), SUM(s.sales_profit)
FROM branch b
LEFT OUTER JOIN sales_data on s.branch_id = b.branch_id
GROUP BY b.branch_id, WEEKDAY(s.sales_date)

Related

Select MySQL return table header as well table body in one query

Hello I am facing hard time trying to realized this task. The problem is that I am not sure in which way this have to be proceeded and couldn't find tutorials or information about realizing this type of task.
The question is I have 2 tables and one connecting table between the two of them. With regular query usually what is displayed is the table header which is known value and them then data. In My case I have to display the table horizontally and vertically since the header value is unknown value.
Here is example of the DB
Clients:
+--------+------ +
| ID | client|
+--------+------ +
| 1 | Sony |
| 2 | Dell |
+--------+------ +
Users:
+--------+---------+------------+
| ID | name | department |
+--------+--------+-------------+
| 1 | John | 1|
| 2 | Dave | 2|
| 3 | Michael| 1|
| 4 | Rich | 3|
+--------+--------+-------------+
Time:
+--------+------+---------------------+------------+
| ID | user | clientid | time | date |
+--------+------+---------------------+------------+
| 1 | 1 | 1 | 01:00:00 | 2017-01-02 |
| 2 | 2 | 2 | 02:00:00 | 2017-01-02 |
| 3 | 1 | 2 | 04:00:00 | 2017-02-02 | -> Result Not Selected since date is different
| 4 | 4 | 1 | 02:00:00 | 2017-01-02 |
| 5 | 1 | 1 | 02:00:00 | 2017-01-02 |
+--------+------+---------------------+------------+
Result Table
+------------+--------+-----------+---------+----------+
| Client | John | Michael | Rich | Dave |
+------------+--------+-----------+---------+----------+
| Sony |3:00:00 | 0 | 2:00:00 | 0 |
+------------+--------+-----------+---------+----------+
| Dell | 0 | 0 | 0 | 2:00:00 |
+------------+--------+-----------+---------+----------+
First table Clients Contains information about clients.
Second table Users Contains information about users
Third Table Time contains rows of time for each users dedicated to different clients from the clients table.
So my goal is to make a SQL Query which will show the Result table. In other words it will select sum of hours which every user have completed for certain client. The number of clients and users is unknown. So first thing that have to be done is Select all users, no matter if they have hours completed or not. After that have to select each client and the sum of hours for each client which was realized for individual user.
The problem is I don't know how to approach this situation. Do I have first to make one query slecting all users then foreach them in the table header and then realize second query selecting the hours and foreaching the body conent, or this can be made with single query which will render the whole table.
The filters for select command are:
WHERE MONTH(`date`) = '$month'
AND YEAR(`date`) ='$year'
AND u.department = '$department'
Selecting single row for tume SUM is:
(SELECT SUM( TIME_TO_SEC( `time` ) ) FROM Time tm
WHERE tm.clientid = c.id AND MONTH(`date`) = '$month' AND YEAR(`date`) ='$year'
This is the query to select the times for a user , here by my logic this might be transformed with GROUP BY c.id (client id), and the problem is that it have to contains another WHERE clause which will specify the USER which is unknown. If the users was known value was for example 5, there is no problem to make 5 subsequent for each user WHERE u.id = 1, 2, 3 etc.
So here are the 2 major problems how to display in same query The users header and them select the sum of hours for each client corresponding the user.
Check out the result table hope to make the things clear.
Any suggestion or answer which can come to resolve this situation will be very helpful.
Thank you!

Mysql, one to many relationship, need most recent

It's a long time since I've worked with MySQL and I'm learning fast, with a lot of help from stackoverflow along the way. This one has me stumped though. I'm certain I've done something similar in the past but despite trying a few things I haven't achieved it yet. I suspect last time I had to utilise PHP code to ignore duplicate rows but I'm not so sure.
I am working with two tables. Table 1 has a unique record for every year, and a reference to a dept. Table 2 stores the head of each dept, and the year they were appointed.
Table 1 Table 2
Year | Dept Dept | Head | Since Year
1982 | 1 1 | Hutchinson | 1979
1983 | 2 1 | Holroyd | 1983
1984 | 2 1 | Farrey | 1987
1985 | 2 2 | Mainwaring | 1983
1986 | 1 2 | Blanche | 1985
1987 | 2 3 | Sunt | 1986
1988 | 3
What I need is a query that returns the person in charge of the referenced dept at the year in question. Like this:
1982 | 1 | Hutchinson
1983 | 2 | Mainwaring
1984 | 2 | Mainwaring
1985 | 2 | Blanche
1986 | 1 | Holroyd
1987 | 2 | Blanche
1988 | 3 | Sunt
MySQL has moved on a fair bit since I last used it. Sub-queries weren't a thing back then and I'm thinking they might help here? Any advice appreciated.
You don't have to use subquery.
Just select valid Heads twice and then discard those where there exists Head appointed later.
SELECT t1.*,t2.Head
FROM Table1 t1
JOIN Table2 t2 ON t1.Dept = t2.Dept AND t1.Year >= t2.`Since Year`
LEFT JOIN Table2 t22 ON t2.Dept = t22.Dept AND t1.Year >= t22.`Since Year` AND t2.`Since Year` < t22.`Since Year`
WHERE t22.Head IS NULL
t2.`Since Year` < t22.`Since Year` find Heads appointed later than current Head
WHERE t22.Head IS NULL select only Heads without successor
Demo
Seeking information about joins
SELECT T1.Year, T1.Dept, T2.Head
FROM Table 1 AS T1
INNER JOIN Table 2 AS T2 ON T1.Dept=T2.Dept

sum a column filtered on another column

I am trying to get the sum of a column that is filtered by another column (distinct values of that column). I have tried "group by" "distinct" "with rollup" and many other variations. I have a bunch of columns showing a customer link. Most services have a redundant side, though some don't have redundancy. I am trying to get a bandwidth total for entire "fnn" column but excluding the redundant side value if it exists. If there is redundancy, then it will be indicated by having the same fnn (and same bandwidth value).
I have been struggling with this for ages. Any help would be fantastic. Solution in mysql or php.
my table looks like:
table name = cust_child
id | cust_name |cp_bw|cp_fnn |other_columns
1 | A | 30 | 11 |xxx
2 | A | 30 | 11 |xxx
3 | B |100 | 22 |xxx
4 | B |100 | 22 |xxx
5 | C |50 | 33 |xxx
Result should look like:
Total bandwidth = 180
SELECT SUM(c.cp_bw) AS bandwith
FROM cust_child c
INNER JOIN (
SELECT c.id
FROM cust_child c
GROUP BY c.cp_fnn
) t1 ON (t1.id = c.id)
http://sqlfiddle.com/#!2/01219/1

Join Row to Previous Closest Date Row

Database data:
id | account | date | random_data
1 | 1 | 01/01/2013 | qw
2 | 2 | 05/01/2013 | er
3 | 2 | 09/01/2013 | ty
4 | 1 | 05/01/2013 | ui
5 | 2 | 11/01/2013 | op
6 | 1 | 12/01/2013 | as
Hi, so let's say I want the records starting from 05/01/2013 - note that prev_date for the 1st row still shows an earlier date than 05/01 meaning that the whole table still needs to be searched.
Result data:
account | cur_date | random_data | prev_date | prev_rand_data
1 | 05/01/2013 | ui | 01/01/2013 | qw
1 | 12/01/2013 | as | 05/01/2013 | ui
2 | 05/01/2013 | er | null | null
2 | 09/01/2013 | ty | 05/01/2013 | er
2 | 11/01/2013 | op | 09/01/2013 | ty
So I'm not sure what is the best, most optimized query I could use for this. I'm not opposed to a php solution but not sure how much better that would be. Some ideas I've considered:
Some sort of join on the same table - not sure how though
Sub queries on the select -
select date as cur_date
, (select max(date)
from table
where date < cur_date
group by account)
as prev_date... - this seems like it could be incredibly intensive
Session variables - set a session variable on each row which will be the previous data for the next row e.g.
select date as cur_date
, #prev_date as prev_date
, #prev_date:=date...
Has anyone had any experience with a problem like this and was there a good solution? Are there any positives negatives with any of the ideas I have that could cause problems in the future?
I would use a combination of sql and application code. Since I am not a php programmer, I will only describe the logic to use for the application part.
First the query.
select account, date, random_data
from thetable
where date >= YourDateVariable
union
select account, date, random_data
from thetable join
(select account acc, max(date) maxdate
from thetable
where date <= YourDateVariable
group by account) x on account = acc and date = max(date)
where date <= YourDateVariable
order by account, date
For the application code, do this:
Set a variable called ThisAccount to 0.
Set a row counter variable to 0.
Create an empty 2D array
Start looping through your query results
Put the account value and random data into the first two columns
of the next available row of the array
Compare the account value to the value of the ThisAccount variable.
If they are the same, get the previous date and random data from
the previous row in the array.
Set the ThisAccount variable to the current account value.
Increment your row counter variable
End of loop.

Display data based on timeframe with SUM

With PHP and MySQL I am trying to display items with most votes over a certain period of time (24 hour, 1 week, 1 year, etc). When someone votes on an item, a table records the user, item id, vote, and time, like so:
Table1
username | itemid | vote | time
asdf | 127 | 1 | 1306726126
asdf | 124 | -1 | 1306726123
bob | 127 | 1 | 1306726129
bob | 124 | 1 | 1306726123
Now, I have another table with item details.
Table2
itemid | name | category | date | etc
What I WANT to do is call a table to display all the data from table 2 for only items with votes in the last 24hours and sort it by the votes. This means I need to SUM votes with TIME < 24 hours, then RIGHT JOIN (?) to my other database? I don't know, I am having difficulty figuring out how I should go about doing this. Any suggestiongs?
Something like this should work.
SELECT SUM(Table1.vote) as votes, Table2.* FROM Table2
LEFT JOIN Table1 ON Table1.itemid=Table2.itemid
WHERE Table1.`time`>=DATE_SUB(Table1.`time`, INTERVAL 24 HOUR)
GROUP BY Table1.itemid
ORDER BY Table1.votes DESC

Categories