mysql select join format from two tables [closed] - mysql

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I'm trying to select data from one table based on a date range of data from another table.
First table: clients with fields firstname, lastname and telephone.
Second table: orders with a field date
I need to get a list of all clients first name, last name and telephone numbers who have orders placed between 2019-12-1 and 2019-12-16.
I've tried many iterations of this mysql select but get way too many hits.
SELECT clients.firstname, clients.lastname, clients.telephone
from clients
JOIN orders ON date BETWEEN '2019-12-1 00:00:00' AND '2019-12-16 23:59:59'
Any insight would be appreciated.

I would assume that the orders has a foreign key column that references the client each order belongs to, and that this column is called client_id. Without this, your schema would not make sense.
I would solve this with exists and a correlated subquery that ensures that the given client placed at least one order during the concerned date range.
select
c.firstname,
c.lastname,
c.telephone
from clients c
where exists (
select 1
from orders o
where
o.client_id = c.client_id
and o.date >= '2019-12-01'
and o.odate < '2019-12-17'
Notes:
this makes use of the half-open strategy to compare the date, which is a good practice in this kind of situation.
this query would take advantage of an index on `orders(client_id, date)

Related

how to make count query and join two table [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
i have two table alamat_penerima and lokasi
alamat penerima table
[this is my record
and then
lokasi table [this is the record
i wont to make two table like this
[view]
I hope you can help me
i have just try this query command :
SELECT COUNT(alamat_penerima.`nama_penerima`) AS penerima, lokasi.`wilayah`
FROM lokasi
INNER JOIN alamat_penerima ON alamat_penerima.`kota_kab` = lokasi.`wilayah`
GROUP BY alamat_penerima.`kota_kab`
but the result is
result
Your question is difficult to understand, so this answer is guesswork. It looks to me like you hope to list the number of recipient addresses in each region, but also show the regions with no addresses.
To do that, you need two subqueries joined together.
This subquery generates the names of all regions.
SELECT DISTINCT wilayah FROM lokasi
This subquery generates a list of regions with the count of addresses in each region. The result set from this subquery, however, omits regions with no addresses in them.
SELECT COUNT(*) num, kota_kab AS wilayah
FROM alamat_penerima
GROUP BY kota_kab
You can test these subqueries individually to determine whether they are correct. It's important to do that.
Finally, you join these two together as if they were tables. (That's why it's called structured query language).
SELECT w.wilayah, a.num
FROM (
SELECT DISTINCT wilayah FROM lokasi
) w
LEFT JOIN (
SELECT COUNT(*) num, kota_kab AS wilayah
FROM alamat_penerima
GROUP BY kota_kab
) a ON w.wilaya = a.wilaya
This will yield what you want, but showing NULL instead of 0 in rows with no addresses. (That's a result of using LEFT JOIN) You can put the 0 values there by using this as the first line of your query instead.
SELECT w.wilayah, IFNULL(a.num,0) num
The design trick is to make your first subquery determine the number of rows in your result set, then to use LEFT JOIN to put information from subsequent subqueries into your results.

Simplify SQL query for me please [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I have a table of multiple employment records of an employee/s where i want to query for a certain range of date.
Parameters are Company.id,date_hired,date_end
Results must be on the range of the specified date and employee.id must only be one if the employee has multiple employment records result must get the latest employment record..
THIS IS WHAT I CURRENTLY HAVE.
SELECT *
FROM employmentrecords
WHERE employmentrecords.id IN(
SELECT MAX(employmentrecords.id)
FROM employmentrecords
WHERE ((employmentrecords.date_end >='2017-08-22'
OR employmentrecords.date_end IS NULL
OR (employmentrecords.date_end <='2017-08-22'
AND employmentrecords.date_end >='2017-08-08'))
AND employmentrecords.date_hired <='2017-08-22')
GROUP
BY employmentrecords.employee_id)
AND employmentrecords.company_id<>0`
Hope any one would suggest a better approach.Thank you
I am not sure if I got your question all clear, this query below will give you the latest employee record if there are multiple user records -
SELECT * FROM employmentrecords WHERE id IN(SELECT MAX(id) FROM employmentrecords
WHERE ((date_end >='2017-08-22'
OR date_end IS NULL
OR (date_end <='2017-08-22' AND date_end >='2017-08-08'))
AND date_hired <='2017-08-22')
GROUP BY employee_id)
AND company_id<>0
and rownum = 1
order by date_hired desc
JFYI, no need to use the table name as alias if there is only one table you are fetching the data from, it just makes it hard to read the query on go.
SELECT id, max(date_hired)
FROM employmentrecords
WHERE ((employmentrecords.date_end >='2017-08-22'
OR employmentrecords.date_end IS NULL
OR (employmentrecords.date_end <='2017-08-22'
AND employmentrecords.date_end >='2017-08-08'))
AND employmentrecords.date_hired <='2017-08-22') group by id

selecting multiple items form multiple tables with min and max [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I'm having a little trouble figuring out this SQL statement. I have three tables employee, job, and job type.
job type is reference table. It has the name of the job, how long that job takes, and how much is charged for that job.
job has records of what job was performed for what client by which employee and the date performed. It links to job type jobname.
employee has name of employee, and employee id. It links to job table by employee id.
I need to display a list of all employees as well as the cheapest and most expensive jobs they did for a given year.
I think I will probably have to have an embedded select and a few joins. Maybe a unionThe complexity is just too far out of my experience. I'm not even sure where to being to be honest.
You should use the employee table as the primary table in your query so you will get one row per employee, even if that employee is associated to 0 jobs. Then use outer joins to the job and job_type tables, group by the employee identifiers, and use the min() and max() aggregate functions on the job table to select the min and max job costs (if any).
Something like this should help you get started:
select employee.employee_id ,
employee.employee_name,
min(job_type.cost),
max(job_type.cost)
from employee
left outer join job on job.employee_id = employee.employee_id
left outer join job_type on job_type.job_type_id = job.job_type_id
group by employee.employee_id,
employee.employee_name

Accessing data from more than one table - SQL [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
Do tables have to be joined to extract data from them?
I believe you mean in one query. There are two ways I can think of to extract data for more than one table in a single query without "joining" them:
Fist is with union
SELECT A, B, C FROM Table1
UNION
SELECT X, Y, Z FROM Table2
You can also do a "cross join" which does not look like a join (and is probably what you are thinking of)
SELECT Table1.A, Table1.B, Table1.C, Table2.X, Table2,Y, Table2,Z
FROM Table1, Table2
As you can see from the syntax there is not relationship from one table to the other. This means that every row in table1 will be combined with every row in table2!
In my experience this is the most common mistake that programmers new to SQL make. They do a cross join when they mean a join and then they GROUP BY or DISTINCT to get the results they want. This is hugely inefficient!
Cross join can be good however, especially when you one of the table has just one row -- then you are adding those values to every row in other table. You are basically selecting single set of values for columns for every row.
Like if you want every row to have the maximum date (this is often done in reports)
SELECT *
FROM Table1, (SELECT MAX(updatedate) as Max_Update FROM Table1) AS MaxDate
Not necessarily, there are other options like Union:
SELECT customerNumber id, contactLastname name
FROM customers
UNION
SELECT employeeNumber id,firstname name
FROM employees
the above example is take from this.
There are other times you can run multiple queries, etc to get data from multiple sources with out a join. It all depends on what you want to do. However, join is a very common--and probably most usual--approach.

Mysql Table and Index Design for Dating Portal [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I am creating a dating portal where we will be asking user around 40-50 questions like religion,caste,date of birth,food preference,smoking/non smoking.
I am asking similar questions on the user preference like age range,religion preference,smoking preference.
I have around 30-40 such preference.
Now I want to show user the matches based on the preference set.
I want to know how I should design MySQL tables and indexes.
Should I create 1 big table of user_preferences and have all preferences indexes.
Should it be multiple column indexes or merge indexes.
Should I keep set of questions in different tables and join them when fetching the data?
m
I think this could be a case for EAV:
You should be able to get the matching user pairs in the descending order (from most matching to least) similar to this:
SELECT *
FROM (
SELECT U1.USER_ID, U2.USER_ID, COUNT(*) MATCH_COUNT
FROM USER U1
JOIN USER_PREFERENCE P1
ON (U1.USER_ID = P1.USER_ID)
JOIN USER_PREFERENCE P2
ON (P1.NAME = P2.NAME AND P1.VALUE = P2.VALUE)
JOIN USER U2
ON (P2.USER_ID = U2.USER_ID)
WHERE U1.USER_ID < U2.USER_ID -- To avoid matching the user with herself and duplicated pairs with flipped user IDs.
GROUP BY U1.USER_ID, U2.USER_ID
) Q
ORDER BY MATCH_COUNT DESC
This just matches the preferences by their exact values. You may want to create additional "preference" tables for range or enum-like values, and replace P1.VALUE = P2.VALUE accordingly. And you may still need special processing if the match is with the data in USER table (such whether user's age falls into other user's preferred age range).
Note the index on {NAME, VALUE} which is meant to help P1.NAME = P2.NAME AND P1.VALUE = P2.VALUE. InnoDB tables are clustered, and one consequence is that secondary indexes contain the copy of PK fields - which in this case causes the index I1 to completely cover the table. Whether MySQL will actually use it is another matter - as always look at the query plan and measure on representative data...
I see something like this:
questions is the list of questions to be answered. question_type is an enumeration that indicates what type of answer is expected (e.g. lookup from question_choices, a date, a number, text, etc.) - whatever types of data you expect to be entered. This, along with the other columns in this table, can drive your input form.
question_answers contains a list of predefined answers to questions (such as a predefined list of religions, or hair color, or eye color, etc.). This can be used to build a drop-down list of values on your input form.
users is pretty self explanatory.
user_characteristics contains a list of my answers to the questionnaire. The weight column indicates how important it is to me that someone looking for me have this same answer. The question_choices_id would be populated if the answer came from a select list built from the question_choices table. Otherwise question_choices_id would be NULL. The converse is true for the value column. value would be NULL if the answer came from a select list built from the question_choices table. Otherwise value would contain the user's hand crafted answer to the question.
user_preferences contains answers to the questionnaire for who I am looking for. The weight column indicates how important it is to me that the person I am looking for have this same answer. The question_choices_id and value columns behave the same as in the user_characteristics table.
SQL to find my match might look something like:
SELECT uc.id
,SUM(up.weight) AS my_weighted_score_of_them
,SUM(uc.weight) AS their_weighted_score_of_me
,SUM(up.weight) + SUM(uc.weight) AS combined_weighted_score
FROM user_preferences up
JOIN user_characteristics uc
ON uc.questions_id = up.questions_id
AND uc.question_choices_id = up.question_choices_id
AND uc.value = up.value
AND uc.users_id != up.users_id
WHERE up.users_id = me.id
GROUP BY uc.id
ORDER BY SUM(up.weight) + SUM(uc.weight) DESC
,SUM(up.weight) DESC
,SUM(uc.weight) DESC
For performance reasons, an index on user_characteristics(id, question_id, question_choices_id, value, and user_id) and an index on user_preferences(id, question_id, question_choices_id, value, and user_id) would be advisable.
Note that the above SQL will return one row for EVERY user except the one making the request. This certainly is NOT desirable. Consequently, one might consider adding HAVING SUM(up.weight) + SUM(uc.weight) > :some_minimum_value - or some other way to further filter the results.
Further tweaks might include only returning people who value an answer as much or more than I do (i.e. their characteristic weight is >= my weight preference weight.