Filter 2 MySQL Tables - mysql

have anyone here tried to filter a table using a field on a separate table? e.g. Table_1 has field of login,group,name and Table_2 has field of login,volume,profit,open_time,close_time.
since Table_2 doesn't have a group i want to filter the login by group so that the result on the query would be filtered already. i have tried the statement below which has no errors but returns no result.
"SELECT DISTINCT a.LOGIN, a.GROUP, b.LOGIN, b.SYMBOL,
SUM(b.VOLUME) NetVolume, SUM(b.PROFIT) NetProfit, b.CLOSE_TIME
FROM TABLE_1 a, TABLE_2 b
WHERE b.CLOSE_TIME BETWEEN '"+dateTimePicker1.Value.ToString("yyyy-MM-dd")+"' AND '"+ dateTimePicker1.Value.ToString("yyyy-MM-dd")+"' AND
a.GROUP NOT IN('group_a','group_b') AND
a.LOGIN = b.LOGIN
ORDER BY NetVolume";
I hope someone can help me on this.
Thanks...

You need to use INNER JOIN
So it would look something like
SELECT DISTINCT a.LOGIN, a.GROUP, b.LOGIN, b.SYMBOL,
SUM(b.VOLUME) NetVolume, SUM(b.PROFIT) NetProfit, b.CLOSE_TIME
FROM a INNER JOIN b ON a.LOGIN = b.LOGIN
WHERE b.CLOSE_TIME BETWEEN '"+dateTimePicker1.Value.ToString("yyyy-MM-dd")+"' AND '"+ dateTimePicker1.Value.ToString("yyyy-MM-dd")+"' AND a.GROUP NOT IN('group_a','group_b') AND
ORDER BY NetVolume";
For more about joins in MySql check
https://dev.mysql.com/doc/refman/5.7/en/join.html

This is too long for a comment. It doesn't address the question directly.
You have two major errors in the code:
Never use commas in the FROM clause. Always use proper explicit JOIN syntax.
Use parameters to pass values into the query.
You may need a LEFT JOIN, but you can't express this using commas.
In addition:
SELECT DISTINCT is almost never needed with GROUP BY.
The GROUP BY does not have all the unaggregated columns.
You should work on writing a clean query. This might actually fix your underlying problem. The problem is probably due to the parameter values that are passed in.

Related

PHP Queries not working

This is working:
SELECT *
FROM ((((defect
JOIN project_testcase ON
defect.Test_Id=project_testcase.Test_Id)
JOIN testcase ON
defect.Test_Id=testcase.Test_Id)
JOIN project_pm ON
project_testcase.Project_Id=project_pm.Project_Id)
JOIN employee ON
employee.Emp_id=project_pm.Emp_id)
However, this does not work:
SELECT *
FROM ((((defect
JOIN project_testcase ON
defect.Test_Id=project_testcase.Test_Id)
JOIN testcase ON
defect.Test_Id=testcase.Test_Id)
JOIN project_pm ON
project_testcase.Project_Id=project_pm.Project_Id)
JOIN employee ON
employee.Emp_id=project_pm.Emp_id)
WHERE Project_Id LIKE '%$categ%'
As I have used JOIN tables and joined using Project_Id. Is that the error?
The first thing I would do to troubleshoot this is to paste it into an SQL formatter. This will help find syntax errors and could help you see a logic error. I would recommend freeformatter.com.
Second you can get rid of the parenthesis.
The Fix
You need to specify what table to get the Project_Id in the WHERE because it is in multiple tables, but for clarity I would always specify what table it comes from.
select
*
from
defect
join
project_testcase
on defect.Test_Id=project_testcase.Test_Id
join
testcase
on defect.Test_Id=testcase.Test_Id
join
project_pm
on project_testcase.Project_Id=project_pm.Project_Id
join
employee
on employee.Emp_id=project_pm.Emp_id
where
project_testcase.Project_Id like '%$categ%'
Project_Id in the where clause is ambiguous, you need to define it as you have done on your joins ie WHERE project_pm.Project_Id like '%$categ%'
In the where clause of the 2nd query you need to tell the rdbms exactly which Project_Id field you want to filter on, since multiple tables contain the Project_Id field, e.g. project_pm.Project_Id.
Starting by removing all those unnecessary parenthesis, formatting and aliases reveals a fairly simple query underneath.
select * --This should really be the columns you actually need instead of all of them
from defect d
join project_testcase ptc on d.Test_Id = ptc.Test_Id
join testcase t on d.Test_Id = t.Test_Id
join project_pm p on ptc.Project_Id = p.Project_Id
join employee e on e.Emp_id = p.Emp_id
where p.Project_Id like '%$categ%'
Of course this begs the question of why do you have text like that in a column named Project_Id? That does not look like a project id to me. And since you are using a leading wildcard you have a nonSARGable query so you have eliminated the ability of index seeks on that column.

SQL join query - join instead of inline query

I would like to use join instead of inline queries but the one I was able to make is giving wrong values.
Please check this link - http://www.sqlfiddle.com/#!2/57cad/9
It has 2 individual queries which give correct values and a join query which gives an incorrect result.
Can someone please help...
Answer shown here: SQLFiddle
Your queries could be improved upon in a few areas which make their JOINing a little more obvious.
In your first query, a better version has the the GROUP BY clause's columns listed in the SELECT clause and your HAVING clause (while working) becomes the WHERE clause (IMO: The best practice is to use aggregate function only in the HAVING clause:)
SELECT usercode, ROUND(coalesce(sum(paymentamount)*0.99,0),2) AS payment
FROM accountpayments
WHERE usercode = 21
GROUP BY usercode;
Your second query can be rewritten as a JOIN (vs. the subquery)
SELECT campaigns.usercode, ROUND(coalesce(sum(lmc_cds.total_spending),0),2) AS total_spending
FROM logsmaincontrols_campaigns_daily_stats AS lmc_cds
JOIN campaigns
ON campaigns.campcode = lmc_cds.campcode
WHERE campaigns.usercode = 21;
Since the queries don't share any tables, I decided to JOIN the queries to each other as derived tables using the usercode as the JOINing column.
SELECT t1.usercode, t1.payment, t2.total_spending
FROM (SELECT usercode, ROUND(coalesce(sum(paymentamount)*0.99,0),2) AS payment
FROM accountpayments
WHERE usercode = 21
GROUP BY usercode) AS t1
JOIN (SELECT campaigns.usercode, ROUND(coalesce(sum(lmc_cds.total_spending),0),2) AS total_spending
FROM logsmaincontrols_campaigns_daily_stats AS lmc_cds
JOIN campaigns
ON campaigns.campcode = lmc_cds.campcode
WHERE campaigns.usercode = 21) AS t2
ON t1.usercode = t2.usercode;

How to correctly use Order By with Inner Joins

I have an SQL statement that looks something like:
SELECT * FROM table1 AS bl
INNER JOIN table2 AS vbsa ON bl.id=vbsa.businesslisting_id AND vbsa.section_id ='70'
INNER JOIN table3 AS vbla ON bl.id=vbla.businesslisting_id AND vbla.location_id='1'
WHERE bl.published = '1'
ORDER BY bl.listing_type DESC
For some reason this will not return any rows, however if I remove the ORDER BY clause it does return rows. Any ideas why this would be?
The column listing_type does exist in the DB and contains number values. It is set as varchar type. I thought maybe this was the problem but I tried a different column (ID) and it still did not work.
Thanks
Robert
Try this
SELECT * FROM table1 AS bl
INNER JOIN table2 AS vbsa ON bl.id = vbsa.businesslisting_id
INNER JOIN table3 AS vbla ON bl.id = vbla.businesslisting_id
WHERE bl.published = 1 AND vbsa.section_id = 70 AND vbla.location_id = 1
ORDER BY bl.listing_type DESC
Also make sure to view the error messages when debugging SQL, trying to fix without seeing these errors is difficult
Found the problem. I have been working on someone else's code and they did not add indexes to the tables in question.
Therefore when I added the sort by attribute and ran the query it was exceeding the MAX_JOIN_SIZE rows.
I added the indexes and now it works perfect.
Thanks for everyones input.

MySQL Combine Data + Count(*) Query FROM 2 tables

I need help with an query. I have a 'members' table and a 'comments' table.
members: userid,name,bday etc...
comments: id,userid,message,rel etc...
Untill now i used 2 queries for membersdata and commentsCount, and combined both in PHP.
My Question. Is it possible to get both (all from members && count of comments) in only one query?
This is not workung...
SELECT members.*, count(comments.*) as count
FROM members, comments
WHERE members.userid=comments.userid
group by members.userid
Does somebody know an other solution?
Here's a cleaned-up version of your query, assuming you want the userid and number of comments for each:
SELECT members.userid, count(*) as count
FROM members
INNER JOIN comments
ON members.userid = comments.userid
GROUP BY members.userid
The issues I addressed:
only selected columns that are either in the group by clause, or have an aggregate function applied to them. It is incorrect to select columns which don't satisfy either of those criteria (although MySQL allows you to do it)
replaced implicit join with explicit join, and moved join condition from where clause to on clause
replaced select ... count(comments.*) with select ... count(*). count(*) works just fine
Thank you Matt
I used your version. And im learning by the was sql-joins.
The problem with my code was the 'count(comments.*)'. Mysql does not like this!
This is working:
SELECT members.*, count(comments.rel) as count
FROM members, comments
WHERE members.userid=comments.userid
group by members.userid

Do you have to join tables "ON" fields or can you just equate them in there where clause?

We have been doing queries a bunch of different ways and queries have been working when we do a
SELECT t.thing FROM table1 t JOIN table2 s WHERE t.something = s.somethingelse AND t.something = 1
and it worked with all queries except one. This one query was hanging forever and crashes our server, but it apparently works if we do it like:
SELECT t.thing FROM table1 t JOIN table2 s ON t.something = s.somethingelse WHERE t.something = 1
We are trying to figure out if the problem is due to the query structure or due to some corruption in the account we are trying to query.
Is the first syntax correct? Thanks.
You need to use the ON clause. Though you can also join with commas, e.g.: SELECT * FROM table1, table2;
Hope that helps!
There are different ANSI formats.. you can use
Select ...
from tbl1 join tbl2 on tbl1.fld = tbl2.fld
OR
select ...
from tbl1, tbl2
where tbl1.fld = tbl2.fld...
The explicit join is the more common format where you are explicitly showing developers after yourself how the tables are related without respect to filtering criteria.
Your first syntax miss the ON. When you join it is mandatory to tell ON what fields the join is happening.
I would recommend using JOIN ON over WHERE to do your joins.
1) your where clause will be easier to read since it will not be pollute by join where clause.
2) your join section is easier to read and understand.
We all agree both method works, but the JOIN one is better due to theses points.
my 2 cents