Combining between two tables in MySQL and getting the distinct answer - mysql

I know this has probably been asked before but I am trying to find the correct way to this and I have been struggling for the past week or so.
So we have two sets of data for example, one table is called 'Order Log' and another is called 'Customer Information'
and here are example of the two data set
NOTE: The order log will sometimes have order from the same customer twice
Order Log Table
Customer ID
Date
Order Number
Order Amount
sgcwi
2022-06-11
124
3
gbtfc
2022-07-09
12
4
crownwood
2022-04-08
123
1
kcsi
2022-02-24
543
1
ulsteri
2022-08-08
423
2
gbtfc
2022-07-08
1254
3
ulsteri
2022-04-08
345
2
kcsi
2022-07-13
64
1
crownwood
2022-07-04
55
1
Customer Information Table
Customer Name
Customer ID
Contact
Sagen Private
sgcwi
email
Granten Viel
gbtfc
phone
Crownwood LTD
crownwood
email
Kings College
kcsi
email
Ulster FC
ulsteri
phone
So what my question is, how do i write an sql query that gives me back the the last order for each customer from the Order Log table withhin a span of the last 6 Months and returns me back the customer name for each of those selected data from the customer Informationt table. like such
The Sql Query Return that i want
Customer Name
Customer ID
Date
Sagen Private
sgcwi
2022-06-11
Granten Viel
gbtfc
2022-06-11
Crownwood LTD
crownwood
2022-07-04
Kings College
kcsi
2022-07-13
Ulster FC
ulsteri
2022-08-08
so far I have figured out to get the result from the Log table that I gave to use the query
"SELECT DISTINCT orderLog.customerID FROM Order WHERE qslogv2.date >= DATE_ADD(NOW(), INTERVAL -3 MONTH);
But I am yet to figure out how do i connect the Customer Information table to this query so it returns me the appropriate customer name along with the query.
I tried using the above query that I mentioned and also tried the UNION keyword in MySQL but to my demise I was not able to get to a point where I got that desired result.

Use JOIN-statement combined with MAX + GROUP BY.
In JOIN you tell what columns match in the joined tables. In your case it is the Customer ID.
With GROUP BY, you divide the rows into sets (based on the customer) and then applies the MAX-function for each of those sets, so that you will get the latest date for each customer.
select
c.name,
c.id,
max(ol.date)
from customerInformation c
join orderLog ol on ol.customerID=c.id
where ol.date between date_sub(now(), interval 6 month) and now()
group by c.name, c.id

Related

SQL count based on timediff and column containing a string

I'm using SQL Workbench.
cust_num date notes
1234 2016-02-01 advice
1234 2016-02-01 something else
1234 2016-02-02 order
1234 2016-02-03 order
4421 2016-02-15 advice
4421 2016-02-17 order
4421 2016-02-18 something else
4421 2016-02-24 order
I know the above is a bit unclear, but basically, there's 3 columns in the above table. One showing customer_num (customer number), one showing date and one showing a notes field.
From the above, I want to perform two queries. I am newish to this so, I hope this is clear. I'm using SQL workbench.
i) I want to count the number of DISTINCT 'customer_num's that placed an order within 4 days of receiving advice.
So the answer based on the table above would be 3. This is because cust_num '1234' made two orders within 4 days and cust_num '4421' made 1 order. So that totals 3
ii)I want to count the number of DISTINCT customer_num's that placed an order within 15 days of receiving advice. Only stipulation is that I don't want to re-count those from (i) that placed an order within 4 days. I want to exclude them.
So the answer to this would be 1. Customer_num '4421' placed 1 order that was bigger than 4 days but smaller than or including 15 days.
Any help really appreciated. Thank you.
One method is to use exists:
select count(distinct cust_num)
from customers t
where exists (select 1
from customers t2
where t2.cust_num = t.cust_num and
t2.date between t.date and date_add(t.date, interval 3 day)
);
The two queries have the same structure. You just need to change the condition in the where clause in the subquery.

MYSQL query - cross tab? Union? Join? Select? What should I be looking for?

Not sure what exactly it is I should be looking for, so I'm reaching out for help.
I have two tables that through queries I need to spit out one. the two tables are as follows:
Transactions:
TransactionID SiteID EmployeeName
520 2 Michael
521 3 Gene
TransactionResponse:
TransactionID PromptMessage Response PromptID
520 Enter Odometer 4500 14
520 Enter Vehicle ID 345 13
521 Enter Odometer 5427 14
521 Enter Vehicle ID 346 13
But what I need is the following, let's call it TransactionSummary:
TransactionID SiteID EmployeeName 'Odometer' 'VehicleID'
520 2 Michael 4500 345
521 3 Gene 5427 346
The "PromptID" column is the number version of "PromptMessage" so I could query off that if it's easier.
A good direction for what this query would be called is the least I'm hoping for. True extra credit for working examples or even using this provided example would be awesome!
For a predefined number of possible PromptID values you can use something like the following query:
SELECT t.TransactionID, t.SiteID, t.EmployeeName,
MAX(CASE WHEN PromptID = 13 THEN Response END) AS 'VehicleID',
MAX(CASE WHEN PromptID = 14 THEN Response END) AS 'Odometer'
FROM Transactions AS t
LEFT JOIN TransactionResponse AS tr
ON t.TransactionID = tr.TransactionID AND t.SiteID = tr.SiteID
GROUP BY t.TransactionID, t.SiteID, t.EmployeeName
The above query uses what is called conditional aggregation: a CASE expression is used within an aggregate function, so as to conditionally account for a subset of records within a group.

Employee available for task between a date range

I have been working on a employee work management project and I am a little stuck. I have 3 tables:
1: employees
empid, empFirst empLast
1 jon smith
2 mark road
3 jane hall
2: holiday
id employee id datestart dateend
1 2 2015-08-07 2015-08-12
2 3 2015-07-4 2015-07-11
3 2 2015-07-20 2015-07-24
3: Task Assigned
id taskid assignedTo(userid) startTask endTask
1 1 1 2015-07-10 2015-07-14
2 2 2 2015-07-29 2015-07-29
3 2 3 2015-07-18 2015-07-30
4 3 2 2015-08-30 2015-09-03
5 4 2 2015-09-10 2015-09-03
I'm not sure how to go about querying the tables to see who is available for a task in a date range (multiple user assigned to the same task). I have a query which I would here:
so if you take the holiday table out if the equation and just run the query below
SELECT employees.empId, employees.empFirst, employees.empLast
FROM employees
LEFT JOIN taskassigned
ON employees.empId = taskassigned.assignedTo
WHERE taskassigned.assignedTo IS NULL or
not (taskassigned.startTask BETWEEN '2015-07-29 14:30:00' AND '2015-07-29 18:30:00'
or taskassigned.endTask BETWEEN '2015-07-29 14:30:00' AND '2015-07-29 18:30:00')
the result I get is:
empId empFirst empLast
1 jon smith (he is available)
2 mark road
2 mark road
As you can see Mark is not available on this date (in the task table).
I would like the query the holiday table first to see if they are on holiday then the task table to see if they already have a task on the date range then the result to show me how is available for the task.
I can't test this at the moment, but try:
SELECT employees.empId, employees.empFirst, employees.empLast
FROM employees
LEFT JOIN taskassigned
ON employees.empId = taskassigned.assignedTo
LEFT JOIN holiday
ON employees.empId = holiday.employeeId
WHERE (
taskassigned.assignedTo IS NULL
OR (
'2015-07-29 14:30:00' NOT BETWEEN taskassigned.startTask AND taskassigned.endTask
AND '2015-07-29 18:30:00' NOT BETWEEN taskassigned.startTask AND taskassigned.endTask
)
)
AND (
holiday.employeeId IS NULL
OR (
'2015-07-29 14:30:00' NOT BETWEEN holiday.dateStart AND holiday.dateEnd
AND '2015-07-29 18:30:00' NOT BETWEEN holiday.dateStart AND holiday.dateEnd
)
)
This would check to see if the specified start date doesn't fall inbetween the assigned task's start or end date, and if the specified end date doesn't fall inbetween the assigned task's start or end date, and then do the same for holidays.
Hi I don't have the right tools to test right now but here is what you can try to do:
when using date comparison:
try to convert/cast to DATE (make sure time is not included) to make sure the result is correct.
as far as I know when using between the start and end date are also included (maybe in some RDMS feature)
Also for including holiday, what you can do is like this (either):
first join with holiday table first then with the result join again with the task assigned table.
or
first join with task assigned table then with the result join again with the holiday table
Sorry for no code included, as I have no time to setup.

MS Access 2007: How to summarize two rows by date and customer

Data:
Customer | Ship_Date | Ship_Weight
Peter 08/01/14 120
Peter 08/01/14 285
How do I summarize these two rows to get an answer by date:
Customer | Ship Date | Ship Weight
Peter 08/01/14 405
As you can see, there are multiple shipments on a single day. I want to summarize it to show unique ship dates with total ship weight.
I am using MS Access 2007.
SELECT Customer, Ship_Date, Sum(Ship_Weight) as Sum_Weight
From tblMyTable
Group By Customer, Ship_Date
You're going to need to make sure your Ship_Date is in Date format only and not DateTime, otherwise it will group by both Date and Time. If necessary, you may need to format that within the query.

Select distinct user_id from a table for each request type

I have a table with 4 columns:
ID, USER_ID, SOURCE, CREATED_DATE
In that table is the following data:
ID USER_ID SOURCE CREATED_DATE
1 25 PURCHASE 2012-01-01 12:30:00
2 26 PLEDGE 2012-01-01 12:40:00
3 25 PLEDGE 2012-01-01 12:50:00
4 25 PURCHASE 2012-01-14 12:00:00
Now as you can see, I have 4 rows of data, and two unique users. User (25) made 3 transactions (two purchases and one pledge), user (26) made one transaction – (one pledge)
Here is what I am trying to achieve:
I need to select ALL transactions from this table, but I want to select a UNIQUE user for each REQUEST TYPE (source), and that row needs to be the EARLIEST TRANSACTION.
My expected result data would be:
ID USER_ID SOURCE CREATED_DATE
1 25 PURCHASE 2012-01-01 12:30:00
2 26 PLEDGE 2012-01-01 12:40:00
3 25 PLEDGE 2012-01-01 12:00:00
User (25) made TWO PURCHASES (one on 2012-01-01 and one on 2012-01-14) – the first is the one that gets returned.
This is the SQL I have come up with so far:
SELECT
Supporter.user_id,
MIN(Supporter.created) as created,
Supporter.*,
Supporter.source
FROM
supporters AS Supporter
GROUP BY Supporter.source
ORDER BY Supporter.created ASC
Now, this gets me really close, except it only selects ONE of the user id’s (the one with two items – a pledge and a purchase). If I could figure out how to select the data on both users, that would be what I need to do! Can anyone see what I am possibly doing wrong here, or missing?
You need to group by source and by user id
Something like this
SELECT
Supporter.user_id,
MIN(Supporter.created) as created,
Supporter.*,
Supporter.source
FROM
supporters AS Supporter
GROUP BY Supporter.user_id, Supporter.source
ORDER BY Supporter.created ASC