I am new to SQL and trying to fetch data using join. Don't know what I am doing wrong. I have two tables.
Table record
recordID|activityName|userID
1 | sale | 5
2 | call | 5
3 | contact | 5
Table activity
activityID|activityData|userID
1 | 50 | 5
2 | 70 | 5
3 | xyz | 5
Result should be
recordID|activityName|activityData|userID
1 | sale | 50 | 5
2 | call | 70 | 5
3 | contact | xyz | 5
But it returns
recordID|activityName|activityData|userID
1 | sale | 50 | 5
2 | call | 70 | 5
3 | contact | xyz | 5
1 | sale | 50 | 5
2 | call | 70 | 5
3 | contact | xyz | 5
1 | sale | 50 | 5
2 | call | 70 | 5
3 | contact | xyz | 5
SELECT * FROM tblrecord tr, tblactivity ta WHERE tr.userID = ta.userID AND tr.userID = '5'
Why is it repeating the result.
PS. userID is the only common field, the activityID and recordID can be different.
First, follow a simple rule: Never use commas in the FROM clause. Always use explicit JOIN syntax.
Second, you seem to want a join on recordId and activityId:
SELECT *
FROM tblrecord tr JOIN
tblactivity ta
ON tr.userID = ta.userID AND
tr.recordId = ta.activityId
WHERE tr.userID = 5;
Also, don't use single quotes if the value is really a number.
Add
GROUP BY userID, activityID
to your query.
Related
Hello and sorry if this questions isn't good formatted, here's my problem:
for simplicity let's say i have a table with products
-----------------------
| id| age |price|name|
----------------------|
| 0 | 0 | 50 | x |
| 1 | 1 | 51 | x |
| 2 | 2 | 52 | x |
| 3 | 3 | 53 | x |
| 4 | 4 | 54 | x |
| 5 | 5 | 55 | x |
| 6 | 6 | 56 | x |
| 7 | 7 | 57 | x |
| 8 | 8 | 58 | x |
-----------------------
I want to get the price for all products of age 0 and 1 with
select price from products where name='x' and(age=0 or age=1)
and it works returning two rows but when the age is the same logically it returns one row and that's my problem how to get it to return again all the rows i want or if something other is wrong with my logic, thank you in advance
One way to achieve this is to build a derived table of the ages that you want to query against and then JOIN that to the products table. Note that you need to use UNION ALL in the derived table to maintain duplicates. Additional values can be searched by adding another UNION ALL SELECT n to the derived table for each value:
SELECT p.price
FROM (SELECT 0 AS age
UNION ALL
SELECT 0) ages
JOIN products p ON p.age = ages.age
WHERE p.name = 'x'
Output:
price
50
50
Demo on dbfiddle
I have a MySQL table like bellow
id | roll | exam_id | course_id | marks | status
----------------------------------------------------------
1 | 01001 | 1 | 1 | 56 | 1
2 | 01002 | 1 | 1 | 68 | 1
3 | 01003 | 1 | 1 | 55 | 1
4 | 01004 | 1 | 1 | 67 | 1
5 | 01001 | 1 | 2 | 54 | 1
6 | 01002 | 1 | 2 | 59 | 1
7 | 01003 | 1 | 2 | 62 | 1
8 | 01004 | 1 | 2 | 63 | 1
9 | 01001 | 2 | 3 | 61 | 1
10 | 01002 | 2 | 3 | 48 | 1
11 | 01003 | 2 | 3 | 22 | 1
12 | 01004 | 2 | 3 | 39 | 1
Now I want to have all the row with exam_id = 1
SELECT * FROM result WHERE exam_id=1 ORDER BY course_id
After that I need to display this table inside HTML after grouping it by roll means one row for each roll that have row-span according to the course number of the result table
Roll | course_id | marks
-----------------------------
01001 | 1 | 56
| 2 | 68
-----------------------------
01002 | 1 | 55
| 2 | 67
-----------------------------
01003 | 1 | 55
| 2 | 62
-----------------------------
01004 | 1 | 67
| 2 | 63
I'm using Codeigniter framework to doing this project. Any suggestions about how I can I do this?
Thank you in advance.
[EDIT]
Current SQL I'm using to do this:
SELECT * FROM `exam_result` JOIN `course` ON `course`.`course_tab_id`=`exam_result`.`result_course` WHERE `exam_id` = '1' AND `result_status` = 1 GROUP BY `exam_result`.`exam_roll`, `course`.`course_tab_id` ORDER BY `exam_result`.`exam_roll` ASC, `course`.`course_id` ASC
Try this but the difference in this table on my first query is that the course title will be included on a single table, I have set the marks as AVG due to so if ever you have duplicate data you will see their average result for the course and roll of a school or whatever you use this structure for
SELECT roll, exam_id, a.course_id, marks, status, course_title, course_credit
FROM
(SELECT roll, exam_id, course_id, AVE(marks) as marks, status FROM result) as a
LEFT JOIN
(SELECT course_id, course_title, course_credit FROM course) as b
ON
a.course_id = b.course_id
WHERE exam_id = '1' -- you can remove this if you wanted all exam appear on your list
GROUP BY roll, exam_id, a.course_id, marks, status, course_title, course_credit
ORDER BY roll, course_id, marks
Try this sql query
SELECT Roll, course_id, AVG(marks)
FROM result WHERE exam='1'
GROUP BY Roll, course_id
ORDER BY roll, course_id, marks
Let's say initially I has table like this without rank or already has rank if php code has running before
ID | STATUS | GRADE | RANK
1 | FAIL | 99 |
2 | FAIL | 95 |
3 | PASS | 40 |
4 | BAR | 99 |
5 | PASS | 70 |
6 | PASS | 85 |
7 | BAR | 80 |
8 | FAIL | 60 |
9 | BAR | 50 |
The ranking system should choose PASS > FAIL > BAR in order. But in that category, when start to enter new category the ranking system will count from previous.
Expected result:
ID | STATUS | GRADE | RANK
1 | FAIL | 99 | 4
2 | FAIL | 95 | 5
3 | PASS | 40 | 3
4 | BAR | 99 |
5 | PASS | 70 | 2
6 | PASS | 85 | 1
7 | BAR | 80 |
8 | FAIL | 60 | 6
9 | BAR | 50 |
Also if can show me some technique to edit the code so that in another day if i plan to upgrade the coding to
ID | STATUS | GRADE | RANK
1 | FAIL | 99 | 4
2 | FAIL | 95 | 5
3 | PASS | 40 | 3
4 | BAR | 99 | 7
5 | PASS | 70 | 2
6 | PASS | 85 | 1
7 | BAR | 80 | 8
8 | FAIL | 60 | 6
9 | BAR | 50 | 9
I have try edit and learning some codes that I found here but I not familiar with session variable. This code will use in cron job/day
You can use user variables to set a rank, and using a sub query joined against the table you want to update you can update the rank in the table.
Something like this:-
UPDATE sometable
INNER JOIN
(
SELECT id,
`status`,
grade,
#rank:=#rank + 1 AS rank
FROM
(
SELECT id,
`status`,
grade
FROM sometable
ORDER BY FIELD(`status`, 'PASS', 'FAIL', 'BAR'), Grade DESC
) sub0
CROSS JOIN (SELECT #rank:=0) sub1
) sub2
ON sometable.id = sub2.id
SET sometable.rank = sub2.rank
Note that I have used the FIELD function to order by the status. In this case it is not strictly necessary (as you could order by status DESC) but given the names of the status would not normally be expect to be in a meaningful alphabetic order FIELD allows you to order in a specified order.
I have two tables:
Users Table:
ID | Name | UserGroupID |
1 | John | 2
2 | Sam | 11
3 | Kiddo | 2
4 | Sony | 3
5 | Jabeen | 1
UsersMachine Table:
ID | MachineID | EmpID
1 | 1 | 1
2 | 2 | 1
3 | 1 | 2
4 | 2 | 2
5 | 2 | 4
6 | 3 | 5
i m looking at single sql to repeat all Users by filtering
FROM UserMachine WHERE MachineID = 2 ALSO FROM Users WHERE UsersGroupID IN (2,11) with these conditions
I m looking at following reasults:
MachineID | UsersName | UsersGroupID
2 | John | 2
2 | Sam | 11
Check out joins. They allow us to associate data from two different tables in a single query:
SELECT um.MachineId, users.Name, users.UsersGroupID FROM UsersMachine um
INNER JOIN Users users ON users.id = um.EmpID
WHERE um.MachineID = 2 AND users.UsersGroupID IN (2,11)
This is probably the best post (visually) I have seen that help me with joins:
http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/
ok, first of all sorry for the title, but I could not work out a better one :(
This is the problem:
I have two tables, properties and properties_rooms, linked each other by the propery ID.
properties table:
+---------------+------------+
| id_properties | pr_title |
+---------------+------------+
| 1 | test |
| 2 | dummy |
+---------------+------------+
properties_rooms table:
+---------------+-------------------+--------------+----------+
| id_prop_rooms | pro_id_properties | pro_id_rooms | pro_size |
+---------------+-------------------+--------------+----------+
| 1 | 1 | 4 | 5.00 |
| 2 | 1 | 18 | 17.00 |
| 3 | 2 | 6 | 12.00 |
| 4 | 2 | 24 | 11.00 |
| 5 | 1 | 4 | 10.00 |
| 6 | 1 | 6 | 10.00 |
| 7 | 1 | 6 | 12.00 |
+---------------+-------------------+--------------+----------+
I'm working on an advanced search, where users can search for a property that has more than a rooms of the same type (ie two bedrooms, 3 bathrooms and so on).
Sadly, I find myself stuck on this, since I can't "filter" the same dataset with multiple clause; if i have to filter only one there will be no problems, since I can use an HAVING clause.
I worked out this select:
SELECT id_properties, pro_id_rooms, COUNT(*) as total,
IF ((pro_id_rooms = 4 AND COUNT(*) >= 2) OR (pro_id_rooms = 6 AND COUNT(*) >= 2), 1, 0) as flag
FROM `properties`
INNER JOIN properties_rooms ON id_properties = pro_id_properties
WHERE id_properties IN (4,10)
GROUP BY id_properties, pro_id_rooms
ORDER BY id_properties
Inside the IN clause there are the properties that I know they have at least one of requested rooms. They came from a previous query since I have to work with GROUP BY and HAVING.
The IF part inside the select is built at run-time, since I get the information from the request.
This is the result:
+---------------+--------------+-------+------+
| id_properties | pro_id_rooms | total | flag |
+---------------+--------------+-------+------+
| 1 | 4 | 2 | 1 |
| 1 | 6 | 2 | 1 |
| 1 | 18 | 1 | 0 |
| 2 | 6 | 1 | 0 |
| 2 | 24 | 1 | 0 |
+---------------+--------------+-------+------+
I think it could work, I only need to add an HAVING flag > 0 and I'm done.
My question is, is there anything better?
Tables aren't very large: properties one could be something like 1k, rooms one about 10k.
I'm afraid that if the user puts too much rooms, the query would become an enormous IF statement...
SELECT id_properties, SUM(pro_id_rooms = 4) AS bedrooms, SUM(pro_id_rooms = 6) AS bathrooms
FROM `properties`
INNER JOIN properties_rooms ON id_properties = pro_id_properties
WHERE id_properties IN (4,10)
GROUP BY id_properties
HAVING bedrooms >= 3 AND bathrooms >= 2
Changes
SUM(pro_id_rooms = 4) AS bedrooms, SUM(pro_id_rooms = 6) AS bathrooms
For each checkbox the user has selected, you need a SUM(pro_id_rooms = x) AS nrofx in your WHERE.
HAVING bedrooms >= 3 AND bathrooms >= 2
This is where you check the number of a particular room.