I have this SQL statement:
SELECT A.service_code_id, A.job_line_id, B.job_code, B.description, C.type_text, D.job_no, E.status, C.priority
FROM job_line_services as A
INNER JOIN job_codes as B
ON A.service_code = B.job_code
INNER JOIN job_type as C
ON B.service_type_id = C.unique_id
INNER JOIN job_lines as D
ON A.job_line_id = D.unique_id
INNER JOIN jobs_in_list as E
ON D.job_no = E.job_no
WHERE E.status = "In Progress" AND D.job_no = 17301
ORDER BY C.priority
This works fine and it returns to following results:
This is great, however I would like to only select the first result, ordered by lowest priority. In the image it would be the first row.
I have tried using GROUP BY and ORDER BY, Selecting DISTINCT job_no, Using the MIN() function on different tables, but I always end up with last row in those results, that one with the priority of 4.
How can I get just the first result in this result set?
Related
SELECT *
FROM `all_salary_slip_details` `assd`
INNER JOIN `employee_master` `em` ON `assd`.`EMPLOYEE_ID` = `em`.`EMPLOYEE_ID`
INNER JOIN `employee_details` `ed` ON `assd`.`EMPLOYEE_ID` = `ed`.`EMPLOYEE_ID`
INNER JOIN `organizations` `o` ON `o`.`ORG_ID` = `assd`.`ORG_ID`
INNER JOIN `months` `mo` ON `mo`.`id` = `assd`.`PAY_MONTH`
This is my query to fetch data from db. I have only 4 rows but in my view I get 48 rows. I dont understand why this happens.
You need to use a GROUP BY clause on a column, then your query will only return a single row for each unique entry in that column.
In your case I'm guessing it would make sense to use the employee name.
What result does this query output?
SELECT assd.PAY_YEAR, assd.PDF, em.EMPLOYEE_NAME, o.ORG_NAME, mo.month_name
FROM all_salary_slip_details assd
INNER JOIN employee_master em
ON assd.EMPLOYEE_ID = em.EMPLOYEE_ID
INNER JOIN organizations o
ON o.ORG_ID = assd.ORG_ID
INNER JOIN months mo
ON mo.id = assd.PAY_MONTH
GROUP BY em.EMPLOYEE_NAME
You will get 1 row returned in your query for each record in a joined table that matches the join condition.
So, if you have multiple records in any one of the employee_master, employee_details, organisations or months tables that match those in all_salary_slip_details you will get additional rows returned. Look at the rows returned, you will see differences in each and where they differ will tell you where the join condition for the table isn't specific enough to return a single row.
I have 3 tables and some fields' names are the same. Here is the first table named semp:
The second one's name semp_k:
And the third is semp_y:
You see, the main table is the first and the others are related it. The first table has got 3 row. So when I fetch it, it must return 3 row. But when I fetch the first table, it multiples returned rows with sum of second and third table. Here is my code:
SELECT s.*, k.*, y.* FROM semp AS s LEFT JOIN semp_k AS k ON s.no = k.semp_no LEFT JOIN semp_y AS y ON s.no = y.semp_no WHERE s.durum = 1 ORDER BY s.bas_t DESC
use MySQL group by
group by s.no
or try this :-
SELECT
s.*, k.*, y.*
FROM
semp AS s
LEFT JOIN semp_k AS k ON s. NO = k.semp_no
LEFT JOIN semp_y AS y ON s. NO = y.semp_no
WHERE
s.durum = 1
GROUP BY s.no
ORDER BY
s.bas_t DESC
You need to use group by.
Your query should be like this ;
SELECT
s.*, k.*, y.*
FROM
semp AS s
LEFT JOIN semp_k AS k ON s. NO = k.semp_no
LEFT JOIN semp_y AS y ON s. NO = y.semp_no
WHERE
s.durum = 1
GROUP BY s.no
ORDER BY
s.bas_t DESC
I have three tables: Station, MonthlyNormalData and SubArea. I'm trying to get all stations in a sub area that have at least one monthly data tied to it. With the following query, I am able to get all stations in a sub area, but this is disregarding the part about monthly data ($region is a variable containing the region name in my PHP script):
SELECT S.station_id, S.name, SA.sub_area_name
FROM dev.Station AS S
INNER JOIN dbo.SubArea AS SA ON S.sub_area_id = SA.sub_area_id
WHERE sub_area_name = '$region'
I have also tried the following query, but it returns one row for each monthly data associated with a station, which is not really what I am looking for (only looking for something that sends me the names of the stations that have at least one monthly data associated to it, not all rows containing that data):
SELECT S.station_id, S.name, SA.sub_area_name
FROM dev.Station AS S
INNER JOIN dbo.SubArea AS SA ON S.sub_area_id = SA.sub_area_id
INNER JOIN data.MonthlyNormalData as MND ON MND.station_id = S.station_id
WHERE sub_area_name = '$region' AND MND.value IS NOT NULL
What would be the query I would need to run to only have one row per station that have a monthly data associated with it within a certain sub area?
You can just use DISTINCT in your second query to remove duplicated rows:
SELECT DISTINCT ...
Since you are only returning records from the tables Station and SubArea using Distinct will work for you.
SELECT distinct S.station_id, S.name, SA.sub_area_name
FROM dev.Station AS S
INNER JOIN dbo.SubArea AS SA ON S.sub_area_id = SA.sub_area_id
INNER JOIN data.MonthlyNormalData as MND ON MND.station_id = S.station_id
WHERE sub_area_name = '$region' AND MND.value IS NOT NULL
Another way to go about it would be to use exist
SELECT S.station_id, S.name, SA.sub_area_name
FROM dev.Station AS S
INNER JOIN dbo.SubArea AS SA ON S.sub_area_id = SA.sub_area_id
WHERE exists (select 1 from data.MonthlyNormalData where station_id = S.station_id) and
sub_area_name = '$region'
I have the following query:
SELECT DISTINCT
SQL_CALC_FOUND_ROWS
unr.RequestID,
unr.UnRead,
unr.FilterID,
r.GroupID,
r.Year,
rv.Bounty
FROM (users_notify_requests as unr, requests_votes as rv)
JOIN requests AS r ON r.ID = unr.RequestID
WHERE unr.UserID = 1 ORDER BY unr.RequestID DESC LIMIT 50
This should return only 2 rows, as there are only two requests where unr.UserID = 1, however it returns 10. 5 versions of the first, and 5 versions of the second, completely identical (respectively). Any idea as to why this might be happening?
EDIT: MySQL version 5.5.29, as requested.
EDIT 2: The print_r() dump: http://pastebin.com/BXujnEpx. The result has incorrect bounty for the given IDs, so something is pretty off with the query.
You're not joining on rv with any criteria, so every row in that table will be returned: It could be that this is the cause of your extra rows.
You probably need a line such as the following (guessing at column names as I don't have your schema):
INNER JOIN request_votes rv ON rv.requestId = r.id
you are joining two tables based on cartesian product or cross join .
FROM (users_notify_requests as unr, requests_votes as rv)
And then you are using a inner join.
JOIN requests AS r ON r.ID = unr.RequestID
To solve the problem you should use inner join in both cases.
Cartesian join is when you join every row of one table to every row of another table. if 1st table contain x rows and y rows in 2nd one the result set will be x*y rows.
SELECT DISTINCT
SQL_CALC_FOUND_ROWS
unr.RequestID,
unr.UnRead,
unr.FilterID,
r.GroupID,
r.Year,
rv.Bounty
FROM users_notify_requests as unr
JOIN requests_votes as rv ON rv.RequestID = unr.RequestID
JOIN requests AS r ON r.ID = unr.RequestID
WHERE unr.UserID = 1 ORDER BY unr.RequestID DESC LIMIT 50
i am trying to get number of posts that i have
Here is my query
$Query="
SELECT t.*,u.*,c.*
FROM posts as t
LEFT JOIN relations as r on r.post_id = t.post_id
LEFT JOIN users as u on t.auther_id = u.auther_id
LEFT JOIN categories as c on c.cate_id = r.cate_id
GROUP BY t.post_id
";
$Query=mysql_query($Query);
$numberOfPosts=mysql_num_rows($Query);
This query is works very well
but i am trying to convert it, i want make it faster
i want use count(*) instead of t.*
because when i use t.*, it gets the full data of posts and categories
but i want to get count only, So i decided to use count(*) but i don't know how to use it with query like this
Edit
i've replaced SELECT t.*,u.*,c.* with SELECT count(t.*)
But i got mysql Error Warning: mysql_fetch_assoc(): supplied argument
Edit 2:
i am trying SELECT count(t.post_title)
I Got this results
Array ( [count(t.post_id)] => 10 )
But i have only 2 posts!
$Query="
SELECT t.*,u.*,c.*
FROM posts as t
LEFT JOIN relations as r on r.post_id = t.post_id
LEFT JOIN users as u on t.auther_id = u.auther_id
LEFT JOIN categories as c on c.cate_id = r.cate_id
GROUP BY t.post_id
";
$Query=mysql_query($Query);
$numberOfPosts=mysql_num_rows($Query);
Let's take a step back and analyze this query for a moment.
You're selecting everything from three out of four tables used in the query. The joins create some logic to limit what you select to the proper categories, authors, etc. At the end of the day you are getting a lot of data from the database, then in PHP simply asking it how many rows were returned (mysql_num_rows). Instead, what #Dagon is trying to suggest in comments, is that you have MySQL simply count the results, and return that.
Let's refactor your query:
$query = "
SELECT COUNT(t.post_id) AS qty
FROM posts as t
LEFT JOIN relations AS r ON r.post_id = t.post_id
LEFT JOIN users AS u ON t.auther_id = u.auther_id
LEFT JOIN categories AS c ON c.cate_id = r.cate_id
GROUP BY t.post_id
";
$result = mysql_query($query);
$result_row = mysql_fetch_assoc($result);
$numberOfPosts = $result_row['qty'];
(You could also use Barattlo's custom execute_scalar function to make it more readable.)
I would need to see your table structures to be of more help on how to optimize the query and get the desired results.
try doing this:
$Query="
SELECT count(t.*) as count_all
FROM posts as t
LEFT JOIN relations as r on r.post_id = t.post_id
LEFT JOIN users as u on t.auther_id = u.auther_id
LEFT JOIN categories as c on c.cate_id = r.cate_id
GROUP BY t.post_id
";
$Query=mysql_query($Query);
$numberOfPosts=mysql_num_rows($Query);
You want to do
SELECT count(t.id) AS count FROM ....
//do query with PDO or whatever you are using
$rows = mysql_fetch_assoc();
$num_rows = $rows['count'];
You should probably simply use
SELECT count(*) as postingcount FROM posts
Why?
Because you do not have a WHERE clause, so there are no restrictions. Your JOINS do not ADD more rows to the resultset, and in the end your GROUP BY merges every duplicate occurance of a post_id that might have occurred because of joining back into one row. The result should only be counted, so assuming that the real number you want to know is the number of data sets inside the table posts, you do not need any join, and doing count(*) really is a very fast operation on tables in MySQL.
Remember to check if mysql_query returns false, because then you have to check mysql_error() and see why your query has an error.