Compare 2 fields of table A with 6 fields of table B - mysql

I've got two tables in my MySQL DB. One contains requiredSkill1, requiredSkillLevel1, requiredSkill2, requiredSkillLevel2, requiredSkill3 and requiredSkillLevel3.
The other table has X rows per user with the following collumns: skill and level.
itemid requiredSkill1 requiredSkillLevel1 requiredSkill2 requiredSkillLevel2 requiredSkill3 requiredSkillLevel3
2410 3319 4 20211 1 NULL NULL
The other table:
userid skill level
21058 3412 4
21058 3435 2
21058 3312 4
Keep in mind, these are just examples.
I want every itemid which has matching values in requiredSkill{1-3} and requiredSkillLevel{1-3}.
Is this even possible with a single query and is this still performant, since the user table contains up to 300 rows per user and the item table has a fixed value of 6000 rows. This will be used in a web application, so I can use Ajax to load ranges of items from the database to decrease loading time.

I don't have the data set up. A SQL Fiddle would be helpful, but I think you want to approach it like this:
SELECT itemid FROM items i
INNER JOIN users u1 ON u1.skill = i.requiredSkill1 AND u1.level >= i.requiredSkillLevel1
INNER JOIN users u2 ON u2.skill = i.requiredSkill2 AND u2.level >= i.requiredSkillLevel2 AND u1.userid = u2.userid
INNER JOIN users u3 ON u3.skill = i.requiredSkill3 AND u3.level >= i.requiredSkillLevel3 AND u3.userid = u1.userid
Someone will solve this for you if you post demo data.

Related

Left Join and Sum

I have two tables, one that lists grants/loans and one that lists individual expenditures. They share an ID column as each expenditure is assigned to a specific grant or loan. I'm trying to use LEFT JOIN to sum the expenditures for all the loans combined, but not the grants.
Here's where I'm at:
SELECT SUM(expenses.total_amt) AS total
FROM expenses WHERE loans_grants.grant_loan_type = 'Loan'
LEFT JOIN loans_grants
ON expenses.grant_loan_id = loans_grants.internal_id;
Any tips much appreciated!
Edit: thanks all, and apologies for the half baked question, it was late and I was in the weeds.
Here's the basic structures:
expenses:
expenses table structure
loans_grants:
loans_grants table structure
I've updated the code based on #jwood74's answer to this:
SELECT l.internal_id, SUM(e.total_amt) amount
FROM loans_grants l
LEFT JOIN expenses e ON e.grant_loan_id = l.internal_id
WHERE grant_loan_type = 'Loan'
group by l.internal_id
which produces this:
internal id
amount
1
3234
4
null
5
7625
7
null
9
null
Please excuse my noviceness, but I'm trying to sum up all expenses for loans, so I'd like to return 3234 + 7625, rather than summing expenses for each loan separately. Thanks for your help!
If you are looking for a SINGLE ROW RETURNED, you do not need to do a group by anything... just the SUM() of what you are looking for.
Second, do not post pictures of your sample data and table structures. Edit your original post and type the values in, even if you copy/paste the data and format it for readability (via Ctrl+K, or the curly brackets {} icon above post editing header area).
In this case, your tables
Loan_Grants table
Internal_id grant_loan_type
1 Loan
2 Grant
3 Grant
4 Loan
5 Loan
6 Grant
7 Loan
8 Grant
9 Loan
Expenses Table
total_amt grant_loan_id
2000 1
245 5
4500 5
2200 5
445 5
185 5
1234 1
50 5
Starting with your Loan_Grants table filtered on just your 'Loan' records
select
sum( e.total_amt ) totalExpenses
from
loan_grants lg
JOIN expenses e
on lg.internal_id = e.grant_loan_id
where
lg.grant_loan_type = 'Loan'
You dont want a left-join unless you explicitly want to see ALL "Loan" entries, even if they have no expenses yet recorded. By doing a regular (inner) JOIN, it means there MUST be a record in the expenses table. Again, based on your needs. If you have 10,000 loans and only 247 loans have expenses, do you want to see all 10,000 or just the 247 and what their totals are. Since you are summarizing to a single return record, JOIN is your best choice here.
For future, ALWAYS try to apply a table.column or alias.column to all your fields so anyone assisting does not have to guess which table the column comes from.
Without knowing the exact format of the two tables, it's a bit hard. But here would be the general idea-
select
l.id,
sum(e.amount) amount
from loans_grants l
left join expenses e on e.grant_loan_id = l.internal_id
where grant_loan_type = 'Loan'
group by l.id

Issue while using inner join with sum

I have two (2) tables:
ps_wk_mp_seller_transaction_history
And ps_wk_mp_seller_order_status
I want to totalize seller_amount only if current_state = 5
For that I have written this:
select sum(seller_amount) as seller_amount
from ps_wk_mp_seller_transaction_history th inner join
ps_wk_mp_seller_order_status os
on os.id_order = th.id_transaction and
os.current_state = 5 and
th.id_customer_seller = 2;
For id_customer_seller=2 I get this 4984.020000 (4950+34.02) and it is exact
But I get 25.848000 instead of NULL for id_customer_seller=5
Can someone help me?
May be you can test yourself, this the code: https://github.com/kulturman/fakerepo
First of all your records have some logic issue, id_transaction have tow transactions with same id_transaction but different amount and different state ! so transaction with id 41 having state 5 and that why customer 5 will not be null because 41 is in state 5.
To fix this
transaction id must be unique id for every transaction in order to differentiate between transaction state and amount
the query should be like this
select sum(seller_amount) as seller_amount
from ps_wk_mp_seller_transaction_history th
left join ps_wk_mp_seller_order_status os
on os.id_order=th.id_transaction
where
th.id_customer_seller = 2
and os.current_state=5
working example here

Getting X results from SQL with multiple tables

(Sorry for my bad english, I'll try to be the clearest)
I want to select 5 conversations (over an undetermined number, there could be 5 or 300 conversations) of one user in a MySQL table, and for each of those, I want to select all the users who talk in it.
In a wonderfull world, I'd like to do it with one query.
My query looks like (tables are in french, plz don't hurt me) :
SELECT mc.mc_id, mc.mc_sujet, mc.mc_statut,
miu.mi_ustatut as uself_statut, miu.mi_datelecture as uself_datelecture,
mi.mi_uid, mi.mi_ustatut, mi.mi_datelecture,
u.u_pseudonyme
FROM msg_individus as miu
LEFT JOIN msg_conversations as mc ON mc.mc_id = miu.mi_mcid
LEFT JOIN msg_individus as mi ON mi.mi_mcid = mc.mc_id
LEFT JOIN u_individus as u ON u.u_id = mi.mi_uid
WHERE miu.mi_uid = :u_id
Where msg_individus is the table with participants of a conversation,
msg_conversations is the table of the conversation (id, subject, status),
u_individus is the table with users' informations.
To select only 5 of those conversations, I added something like
GROUP BY mc.mc_id,
LIMIT 0,5
But of course, only one user per conversation is given is this way.
I also tried to write GROUP BY mc.mc_id, mi.mi_uid but this, like no writting a GROUP BY condition, returns 5 iterations like :
(Conversation 1 has two users, conversation 2 has one, conversation 3 has four)
Iteration 1 : conversation 1, user 1
Iteration 2 : conversation 1, user 2
Iteration 3 : conversation 2, user 1
Iteration 4 : conversation 3, user 1
Iteration 5 : conversation 3, user 2
What I want is to get five CONVERSATIONS with all their datas (whatever the number of users in it, etc)
I guess I'll have to use two queries (after getting the 5 conversations, I'll get the users per conversations), but maybe you guys can light me with your knowledges.
Thx.
Use a subquery to get five conversations. I also suggest that you replace the outer joins with inner joins. I think the table keys should all have matches:
SELECT mc.mc_id, mc.mc_sujet, mc.mc_statut,
miu.mi_ustatut as uself_statut, miu.mi_datelecture as uself_datelecture,
mi.mi_uid, mi.mi_ustatut, mi.mi_datelecture,
u.u_pseudonyme
FROM (SELECT miu.*, mc.*
FROM msg_individus miu JOIN
msg_conversations mc
ON mc.mc_id = miu.mi_mcid
WHERE miu.mi_uid = :u_id
ORDER BY rand() -- not necessary, but why not?
LIMIT 5
) ic
msg_individus mi
ON mi.mi_mcid = ic.mc_id JOIN
u_individus u
ON u.u_id = ic.mi_uid;

mysql select statement. why does it return 6 of the same record

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;

MYSQL - How to check if a user is following another user, potentially through a subselect?

I'm fetching a list of activities (activities) and using a left join to grab the user data (users) who created the activity. Within my application users have the ability to follow one another.
This is my current query, which grabs all activities not posted by yourself ($user_id)
SELECT
activities.id, activities.user_id, users.id, users.name
FROM
activities
LEFT JOIN
users on activities.user_id = users.id
WHERE
users.id != $user_id
Aside from the activities + users tables, I have a another table in my application called followers:
followers
id | user_id_1 | user_id_2 | followed_back
1 1 3 1
2 2 3 0
3 3 1 1
I need to check whether you ($user_id) have followed a particular user joined to each activity and perhaps call this new field "user_followed" which represents a true/false/null value?
For example, I'm user_id = 1. Based on the above table, this means I have followed user_id 3. When an activity is fetched and user_id 3 is joined / responsible, the new field "user_followed" would be true.
Therefore, I think I'd need to incorporate another SELECT query, checking if the user is being followed:
(SELECT
*
FROM
followers
WHERE
user_id_1 = $user_id AND user_id_2 = users.id
)
I'm just largely unsure of how to incorporate this into my initial query and create a new field representing yes or no. Any help would be much appreciated!