How to get the right value using a join - mysql

This is driving me nuts, I'm sure it's rather simple but can't get it right.
Having a table holding ratevalues for different years:
Ratevaluetable
Year Value A Value B Value C
2009 10 15 20
2010 12 18 22
2011 14 21 25
Then I have another persontable:
User Time Price
john 2010 value B
Tina 2009 Value C
Bill 2011 Value C
Now what I need is to join the 2 tables so that I get the value in the Price column substituted with the data from the Ratevaluetable.
I can join on time on year, but the I don't know how to join to the Value fields?

This is not possible with your current database schema. Joins connect tables by matching column values; what you propose to do here is match a column value with a column name, which is impossible.
What would be possible is:
Table ValueTypes:
Id Description
1 Value A
2 Value B
3 Value C
Table RateValueTable:
Year ValueTypeId Value
2009 1 10
2009 2 15
2009 3 20
Table User:
User Time ValueTypeId
john 2009 2
Given the above schema, you could join User to RateValueTable in the obvious manner.

It is possible, but it's not really the best database design. You'd have to do a conditional statement to figure out which column of Ratevaluetable to get.
SELECT persontable.User, persontable.Time, CASE WHEN persontable.Price = 'value a' THEN `Ratevaluetable.Value A` WHEN persontable.Price = 'value b' THEN `Ratevaluetable.Value B` WHEN persontable.Price = 'value c' THEN `Ratevaluetable.Value C` AS 'price' FROM persontable, Ratevaluetable WHERE persontable.Time = Ratevaluetable.year

Related

Combining between two tables in MySQL and getting the distinct answer

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

Deleting max value of different names in sql table

I have a table as follows:
Name Value Date
A 10 2016
A 20 2017
A 30 Null
B 40 2015
B 50 2014
B 60 Null
C 70 2017
C 80 2018
C 90 2019
I want to find max value of corresponding names which have Dates. If date is null that row should be deleted and the next corresponding value to be considered and displayed.
I have got max value but not able to delete that row
You can try below -
select name,max(val)
from tablename
where date is not null
group by name

Finding dates within one year of each other

I am trying to determine the number of employees who left the company within 1 year of being hired:
SELECT
Min(O896IA_VEMPPRSA.EMP_RHR_DT) AS MinOfEMP_RHR_DT,
Max(O867IA_VJOBHST.REC_EFF_STT_DT) AS MaxOfREC_EFF_STT_DT,
O896IA_VEMPPRSA.SYS_EMP_ID_NR
FROM O896IA_VEMPPRSA
INNER JOIN O867IA_VJOBHST
ON O896IA_VEMPPRSA.SYS_EMP_ID_NR = O867IA_VJOBHST.SYS_EMP_ID_NR
WHERE
O867IA_VJOBHST.EMP_ACN_TYP_CD="TER"
GROUP BY
O896IA_VEMPPRSA.SYS_EMP_ID_NR;
EMP_RHR_DT is the original hire date, and REC_EFF_STT_DT is the date they quit/were fired. Again I need the REC_EFF_STT_DT to be within 365 days of the EMP_RHR_DT. Any thoughts?
Example of RHR Date Changes. IN some cases there will only be one job but still a negative days worked, in other cases it is because it is selecting the wrong job.
Job MinOfEMP_RHR_DT MaxOfREC_EFF_STT_DT daysworked SYS_EMP_ID_NR
abc1 10/24/2012 4/15/2013 173 123456
abc1 4/25/2013 4/13/2013 -12 234567
abc3 7/8/2013 1/4/2013 -185 891234
abc4 7/8/2013 7/29/2013 21 891234
Assuming O896IA_VEMPPRSA is master table and O867IA_VJOBHST is detail table with the following data:
O896IA_VEMPPRSA:
ID EMP_RHR_DT SYS_EMP_ID_NR Empname
1 8/10/2012 1 John
2 10/10/2012 2 Matthew
O867IA_VJOBHST:
ID SYS_EMP_ID_NR EMP_ACN_TYP_CD REC_EFF_STT_DT
1 1 Married 1/1/2003
2 1 Became dad 8/1/2003
3 1 TER 9/10/2013
5 2 Remarried 1/1/2003
6 2 Remarried 8/1/2003
7 2 TER 9/10/2013
You could do this to get the number of days worked:
SELECT
Min(O896IA_VEMPPRSA.EMP_RHR_DT) AS MinOfEMP_RHR_DT,
Max(O867IA_VJOBHST.REC_EFF_STT_DT) AS MaxOfREC_EFF_STT_DT,
Max(O867IA_VJOBHST.REC_EFF_STT_DT) - Min(O896IA_VEMPPRSA.EMP_RHR_DT) as daysworked,
O896IA_VEMPPRSA.SYS_EMP_ID_NR
FROM O896IA_VEMPPRSA
INNER JOIN O867IA_VJOBHST
ON O896IA_VEMPPRSA.SYS_EMP_ID_NR = O867IA_VJOBHST.SYS_EMP_ID_NR
WHERE
O867IA_VJOBHST.EMP_ACN_TYP_CD="TER"
GROUP BY
O896IA_VEMPPRSA.SYS_EMP_ID_NR;
HAVING
(Max(O867IA_VJOBHST.REC_EFF_STT_DT) - Min(O896IA_VEMPPRSA.EMP_RHR_DT)) < 365;
The solution is with the datediff function. You will end up with a constraint like:
WHERE DateDiff("yyyy",hiringDate, endingDate)<1
Please check the exact syntax for the DateDiff function in the MS-Access help

split table into multiple tables based on not null criteria in sqlserver/ssis

I have a scenario where i have an input table table (Dynamic Table number of columns are not fixed) like below and need to get multiple tables based on not null values
Input table
ID Name Mobile Year value
1 john 1238769 2001 35
2 tommy 3423456 2001 56
3 smith 8761934 2007 65
4 NULL 4783921 2005 78
5 robert 8549543 2008 18
6 mary 5648404 2011 40
7 NULL 6729113 2003 59
8 NULL NULL 2006 10
9 cathy NULL 2010 35
10 jessi NULL 2012 45
So i need something like below tables based on not null
Output table1
ID Name Mobile Year value
1 john 1238769 2001 35
2 tommy 3423456 2001 56
3 smith 8761934 2007 65
5 robert 8549543 2008 18
6 mary 5648404 2011 40
output table 2
ID Mobile Year value
4 4783921 2005 78
7 6729113 2003 59
output table3
ID Name Year value
9 cathy 2010 3578
10 jessi 2012 45
and finally output table 4
ID Year value
8 2006 10
INSERT INTO OutputTable1
SELECT yourtable.*
FROM yourtable
WHERE Name IS NOT NULL and Mobile IS NOT NULL
INSERT INTO OutputTable2
SELECT yourtable.*
FROM yourtable
WHERE Name IS NULL and Mobile IS NOT NULL
INSERT INTO OutputTable3
SELECT yourtable.*
FROM yourtable
WHERE Name IS NOT NULL and Mobile IS NULL
INSERT INTO OutputTable4
SELECT yourtable.*
FROM yourtable
WHERE Name IS NULL and Mobile IS NULL
Since the number of columns is unknown (as well as their names, probably), you'll have to use dynamic SQL. Assuming the input table has a PK and the PK's name is either known beforehand or can somehow be determined easily, here's one approach to solving the problem:
Query metadata to determine the table's column names.
Using the list of names, build and execute a query that would:
unpivot all the data (non-PK) columns (converting them all into strings, apparently);
group the unpivoted result set by the PK and GROUP_CONCAT the names into two lists:
1) columns with non-null values, in the form of 'name1,name2,...', as SelectList,
2) columns with null values, like this: 'name1 IS NULL AND name2 IS NULL AND ...', as NullCondition;
Using distinct SelectList and NullCondition values from the last result set and the following template, build a series of queries to retrieve data from the original table:
' SELECT ' + SelectList +
' FROM yourtable' +
' WHERE ' + NullCondition
I'm not sure in which of the two products (SQL Server or MySQL) it would be more convenient to implement the above. It is true that SQL Server doesn't have a dedicated aggregate concatenation function like MySQL's GROUP_CONCAT. Workarounds are not unknown, though. MySQL, on the other hand, doesn't support this very handy UNPIVOT clause that SQL Server has. But again, alternatives to using UNPIVOT exist as well.

MS Access: Using Single form to enter query parameters in MS access

compliment of the day.
Based on the previous feedback received,
After creating a Ticket sales database in MS Access. I want to use a single form to Query the price of a particular ticket at a particular month and have the price displayed back in the form in a text field or label.
Below are sample tables and used query
CompanyTable
CompID CompName
A Ann
B Bahn
C Can
KK Seven
- --
TicketTable
TicketCode TicketDes
10 Two people
11 Monthly
12 Weekend
14 Daily
TicketPriceTable
ID TicketCode Price ValidFrom
1 10 $35.50 8/1/2010
2 10 $38.50 8/1/2011
3 11 $20.50 8/1/2010
4 11 $25.00 11/1/2011
5 12 $50.50 12/1/2010
6 12 $60.50 1/1/2011
7 14 $15.50 2/1/2010
8 14 $19.00 3/1/2011
9 10 $40.50 4/1/2012
Used query:
SELECT TicketPriceTable.Price
FROM TicketPriceTable
WHERE (((TicketPriceTable.ValidFrom)=[DATE01]) AND ((TicketPriceTable.TicketCode)=[TCODE01]));
In MS Access, a mini boxes pops up to enter the parameters when running the query. How can I use a single form to enter the parameters for [DATE01] and [TCODE01]. and the price displayed in the same form in a textfield (For further calculations).
Such as 'Month' field equals to input to [DATE01] parameter
'Ticket Code' equals to input for [TCODE01] parameter
Textfield equals to output of the query result (Ticket price)
If possible, I would like to use only the Month and Year in this format MM/YYYY.The day is not necessarry. How can I achieve it in MS Access?
If any question, please don't hesitate to ask
Thanks very much for your time and anticipated feedback.
You can refer to the values in the form fields by using expressions like: [Forms]![NameOfTheForm]![NameOfTheField]
Entering up to 300 different types of tickets
Answer to your comment referring to Accessing data from a ticket database, based on months in MS Access)
You can use Cartesian products to create a lot of records. If you select two tables in a query but do not join them, the result is a Cartesian product, which means that every record from one table is combined with every record from the other.
Let's add a new table called MonthTable
MonthNr MonthName
1 January
2 February
3 March
... ...
Now if you combine this table containing 12 records with your TicketTable containing 4 records, you will get a result containing 48 records
SELECT M.MonthNr, M.MonthName, T.TicketCode, T.TicketDes
FROM MonthTable M, TicketTable T
ORDER BY M.MonthNr, T.TicketCode
You get something like this
MonthNr MonthName TicketCode TicketDes
1 January 10 Two people
1 January 11 Monthly
1 January 12 Weekend
1 January 14 Daily
2 February 10 Two people
2 February 11 Monthly
2 February 12 Weekend
2 February 14 Daily
3 March 10 Two people
3 March 11 Monthly
3 March 12 Weekend
3 March 14 Daily
... ... ... ...
You can also get the price actually valid for a ticket type like this
SELECT TicketCode, Price, ActualPeriod AS ValidFrom
FROM (SELECT TicketCode, MAX(ValidFrom) AS ActualPeriod
FROM TicketPriceTable
WHERE ValidFrom <= Date
GROUP BY TicketCode) X
INNER JOIN TicketPriceTable T
ON X.TicketCode = T.TicketCode AND X.ActualPeriod=T.ValidFrom
The WHERE ValidFrom <= Date is in case that you entered future prices.
Here the subquery selects the actually valid period, i.e. the ValidFrom that applies for each TicketCode. If you find sub-selects a bit confusing, you can also store them as query in Access or as view in MySQL and base a subsequent query on them. This has the advantage that you can create them in the query designer.
Consider not creating all your 300 records physically, but just getting them dynamically from a Cartesian product.
I let you put all the pieces together now.
In Access Forms you can set the RecordSource to be a query, not only a table. This can be either the name of a stored query or a SQL statement. This allows you to have controls bound to different tables through this query.
You can also place subforms on the main form that are bound to other tables than the main form.
You can also display the result of an expression in a TextBox by setting the ControlSource to an expression by starting with an equal sign
=DLookUp("Price", "TicketPriceTable", "TicketCode=" & Me!cboTicketCode.Value)
You can set the Format of a TextBox to MM\/yyyy or use the format function
s = Format$(Now, "MM\/yyyy")