get data from to tables ! - sql

i have user list , and i have select box to filter userlist one of the select box options is show by most viewed so i have also need user information too .
i want to sort my users based on most viewed profile in my user list .
i have these two tables but i don't know how to right correct query to make this happen .
i used grouping like this :
$sql ="select userid , count(*) form profile_visit group by userid " ;
but it's not make sense to me , i don't think this query will help me at all .
+-----------+---------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------------+------+-----+-------------------+----------------+
| userid | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(128) | NO | | NULL | |
| password | char(40) | NO | | NULL | |
| email | varchar(128) | NO | | NULL | |
| name | varchar(256) | NO | | NULL | |
| lastname | varchar(256) | NO | | NULL | |
| job | varchar(256) | NO | | NULL | |
| birthdate | varchar(100) | NO | | NULL | |
| address | varchar(1024) | NO | | NULL | |
| website | varchar(100) | NO | | NULL | |
| tel | varchar(100) | NO | | NULL | |
| role | tinyint(1) | NO | | 0 | |
| reg_date | timestamp | NO | | CURRENT_TIMESTAMP | |
+-----------+---------------+------+-----+-------------------+----------------+
and profile_visit table like this
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| ip_address | varchar(70) | NO | | NULL | |
| userid | int(11) | NO | | NULL | |
+------------+-------------+------+-----+---------+----------------+

Try something like this:
$sql ="SELECT userid , COUNT(*) AS visits FROM profile_visit GROUP BY userid ORDER BY visits DESC" ;
That should group as you were expecting, but order the results in descending order based on the number of visits they have had.
I would ask whether it is necessary to have a separate table? Do you need details of all the visits to be stored, or could you just increment a "visits" integer for each user?

Disregarding the typo in form from your query looks reasonable. It should give you the profile identifiers and their view counts.
As I understand your question, you simply need to get the data out sorted in descending order, which is achievable by simply appending an order by to your query (using an alias for the aggregated column makes it an easier read):
select userid , count(*) as visitcount
from profile_visit
group by userid
order by visitcount

Related

SQL multiple inclusive joins

Below is schema description. I would like to construct a query that for a given user will return all the cases that are shared directly via case_users OR indirectly via case_groups table. Here is my attempt, where I pull the groups the user belongs to upfront:
SELECT * FROM `cases`
INNER JOIN `case_users` ON `cases`.`id` = `case_users`.`case_id`
INNER JOIN `case_groups` ON `cases`.`id` = `case_groups`.`case_id`
WHERE `case_users`.`user_id` = '<USER_ID>'
OR `case_groups`.`group_id` IN (<USER_GROUP_LIST>)
EXPLAIN returns the following: Impossible WHERE noticed after reading const table...
How can I get it done? Ideally I would like to retrieve all the cases in a single shot - without pulling the USER_GROUP_LIST - groups that the user belongs to.
mysql> describe users;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
+-------------+--------------+------+-----+---------+----------------+
mysql> describe cases;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
+-------------+--------------+------+-----+---------+----------------+
mysql> describe case_users;
+-------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------+------+-----+---------+-------+
| user_id | int(11) | NO | PRI | NULL | |
| case_id | int(11) | NO | PRI | NULL | |
+-------------+---------+------+-----+---------+-------+
mysql> describe case_groups;
+-------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------+------+-----+---------+-------+
| case_id | int(11) | NO | PRI | NULL | |
| group_id | int(11) | NO | PRI | NULL | |
+-------------+---------+------+-----+---------+-------+
mysql> describe group_users;
+-------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------+------+-----+---------+-------+
| group_id | int(11) | NO | PRI | NULL | |
| user_id | int(11) | NO | PRI | NULL | |
+-------------+---------+------+-----+---------+-------+
Your joins will only return cases whose Id is in both the case_users and case_groups..
If its one or the other, then you need 2 queries, which you can UNION to get all the results in a single resultset:
SELECT `cases`.* FROM `cases`
INNER JOIN `case_users` ON `cases`.`id` = `case_users`.`case_id`
WHERE `case_users`.`user_id` = '<USER_ID>'
UNION
SELECT `cases`.* FROM `cases`
INNER JOIN `case_groups` ON `cases`.`id` = `case_groups`.`case_id`
WHERE `case_groups`.`group_id` IN (SELECT `group_users`.`group_id`
FROM `group_users`
WHERE `group_users`.`user_id` = '<USER_ID>')

MySql query same table to gather to-date and year-to-date information

I've been struggling with this problem for hours, even though I'm sure there is an easy answer. I'm attempting to gather monthly information and year-to-date information from the same table. I'm also joining a second table to gather the group name.
expense Table:
+-----------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+---------------+------+-----+---------+----------------+
| id | int(5) | NO | PRI | NULL | auto_increment |
| account | char(14) | NO | | NULL | |
| batch | int(5) | NO | | NULL | |
| date | date | NO | | NULL | |
| description | varchar(50) | NO | | NULL | |
| debit | decimal(10,2) | NO | | NULL | |
| credit | decimal(10,2) | NO | | NULL | |
| account_data_id | varchar(14) | NO | | NULL | |
+-----------------+---------------+------+-----+---------+----------------+
account_data table:
+--------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+----------------+
| id | int(5) | NO | PRI | NULL | auto_increment |
| account_code | varchar(14) | NO | | NULL | |
| group_name | varchar(30) | NO | | NULL | |
+--------------+-------------+------+-----+---------+----------------+
I can easily come up with either monthly or year-to-date information, but no matter what I do I'm not able to have both. Below is the closest I can come up with, but it takes forever to execute and the results are not whats expected:
SELECT account_data.group_name, sum(m.debit)- sum(m.credit) AS month, sum(y.debit)- SUM(y.credit) AS year
FROM account_data
INNER JOIN expense m ON m.account_data_id = account_data.id
AND MONTH(m.`date`) IN (7,8,9,10,11,12)
LEFT JOIN expense y ON y.account_data_id = account_data.id
AND MONTH(y.`date`) IN (7)
GROUP BY account_data.group_name
This is what I'm looking to accomplish:
+--------------+----------+---------+
| group_name | month | year |
+--------------+----------+---------+
| Payroll | 10,000 | 50,000 |
| Payroll Tax | 1,000 | 5,000 |
| Benefits | 500 | 1,000 |
+--------------+----------+---------+
Any help is greatly appreciated. I'm new here and I hope I've followed all rules and have provided any of you with enough information to help, but if not let me know and I will provide more.
#philwinkle -Your solution, properly modified:
SELECT ad.group_name,
IF(MONTH(e.date) IN (7,8,9,10,11,12), SUM(e.debit) - SUM(e.credit),'' ),
IF(MONTH(e.date) = 7, SUM(e.debit) - SUM(e.credit),'' )
FROM account_data ad
LEFT JOIN expense_2011 e ON e.account_data_id = ad.id
WHERE e.account_data_id > 7
GROUP BY ad.group_name
The solution here is to use conditional sums... I'm going to put pseudo-code and I'll edit when I'm 100% positive the below solution validates and works:
SELECT ad.group_name,
(if(e.account_data_id IN (7,8,9,10,11,12),sum(e.debit)- sum(e.credit)) AS month,
(if(e.account_data_id=7,sum(e.debit)- sum(e.credit)) AS year
FROM account_data ad
LEFT JOIN expense e ON e.account_data_id = ad.id
WHERE e.account_data_id > 7
GROUP BY account_data.group_name

Return null on condition in sub-table

Say i have 2 tables, person and job.
+--------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| job_id | int(11) | NO | | NULL | |
+--------+--------------+------+-----+---------+----------------+
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| j_id | int(11) | NO | PRI | NULL | auto_increment |
| j_name | varchar(255) | NO | | NULL | |
| j_active | tinyint(1) | NO | | 0 | |
+----------+--------------+------+-----+---------+----------------+
How would i do a select where it only returns a job_id where j_active = 1 and otherwise return 0 or NULL? So, I would want to always return all persons but when their job isn't active i dont want to return their job id
select * from person p left join job j on p.job_id=j.j_id and j.j_active=1
A case statement should work. Something like:
select name, case when j_active=1 then job_id else null end as job_id
from person join job on (person.job_id=job.j_id)

Error: The used SELECT statements have a different number of columns

Why am I getting ERROR 1222 (21000): The used SELECT statements have a different number of columns from the following?
SELECT * FROM friends
LEFT JOIN users AS u1 ON users.uid = friends.fid1
LEFT JOIN users AS u2 ON users.uid = friends.fid2
WHERE (friends.fid1 = 1) AND (friends.fid2 > 1)
UNION SELECT fid2 FROM friends
WHERE (friends.fid2 = 1) AND (friends.fid1 < 1)
ORDER BY RAND()
LIMIT 6;
users:
+------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------+------+-----+---------+----------------+
| uid | int(11) | NO | PRI | NULL | auto_increment |
| first_name | varchar(50) | NO | | NULL | |
| last_name | varchar(50) | NO | | NULL | |
| email | varchar(128) | NO | UNI | NULL | |
| mid | varchar(40) | NO | | NULL | |
| active | enum('N','Y') | NO | | NULL | |
| password | varchar(64) | NO | | NULL | |
| sex | enum('M','F') | YES | | NULL | |
| created | datetime | YES | | NULL | |
| last_login | datetime | YES | | NULL | |
| pro | enum('N','Y') | NO | | NULL | |
+------------+---------------+------+-----+---------+----------------+
friends:
+---------------+--------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------------------------------+------+-----+---------+----------------+
| friendship_id | int(11) | NO | MUL | NULL | auto_increment |
| fid1 | int(11) | NO | PRI | NULL | |
| fid2 | int(11) | NO | PRI | NULL | |
| status | enum('pending','accepted','ignored') | NO | | NULL | |
+---------------+--------------------------------------+------+-----+---------+----------------+
UNIONs (UNION and UNION ALL) require that all the queries being UNION'd have:
The same number of columns in the SELECT clause
The column data type has to match at each position
Your query has:
SELECT f.*, u1.*, u2.* ...
UNION
SELECT fid2 FROM friends
The easiest re-write I have is:
SELECT f.*, u.*
FROM FRIENDS AS f
JOIN USERS AS u ON u.uid = f.fid2
WHERE f.fid1 = 1
AND f.fid2 > 1
UNION
SELECT f.*, u.*
FROM FRIENDS AS f
JOIN USERS AS u ON u.uid = f.fid1
WHERE f.fid2 = 1
AND f.fid1 < 1
ORDER BY RAND()
LIMIT 6;
You've LEFT JOIN'd to the USERS table twice, but don't appear to be using the information.

MYSQL select statement conditions

query:
SELECT u.deviceID, u.userName, u.contactNo, u.rating
FROM User u
INNER JOIN TaxiQuery t ON u.deviceID = t.seat1
OR u.deviceID = t.seat2
OR u.deviceID = t.seat3
OR u.deviceID = t.seat4
WHERE t.queryID = 3;
+--------------------------------------+----------+-----------+--------+
| deviceID | userName | contactNo | rating |
+--------------------------------------+----------+-----------+--------+
| 00000000-0000-1000-8000-0016CB8B3C8E | uuuuuu | 55555 | 5 |
+--------------------------------------+----------+-----------+--------+
describe user;
+-----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| deviceID | varchar(100) | NO | PRI | NULL | |
| userName | varchar(100) | YES | | NULL | |
| contactNo | int(11) | YES | | NULL | |
| emailAddr | varchar(100) | YES | | NULL | |
| rating | int(11) | YES | | NULL | |
+-----------+--------------+------+-----+---------+-------+
mysql> describe taxiQuery;
+--------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+----------------+
| queryID | int(11) | NO | PRI | NULL | auto_increment |
| destination | varchar(100) | YES | | NULL | |
| deptTime | varchar(100) | YES | | NULL | |
| startingPt | varchar(100) | YES | | NULL | |
| boardingPass | varchar(100) | YES | | NULL | |
| miscInfo | varchar(100) | YES | | NULL | |
| seat1 | varchar(100) | YES | | NULL | |
| seat2 | varchar(100) | YES | | NULL | |
| seat3 | varchar(100) | YES | | NULL | |
| seat4 | varchar(100) | YES | | NULL | |
+--------------+--------------+------+-----+---------+----------------+
What i want is to display the user's information if they exist in (seat1/seat2/seat3/seat4) in TaxiQuery. But i am only able to output one result when they are suppose to be three.
May i know how do i modify mysql statement to display the user's information when (seat1-4 is the foreign key to the deviceID of User's table) when seat1, seat2, seat3, seat4 contains the deviceID of the users?
As far as I can tell, it should work if you don't do an INNER join. I think the INNER keyword is telling mySQL to only include each source a maximum of once, so it will only use one copy of the TaxiQuery, when you actually need up to four (one per seat).