I have two tables in a database that I would like to combine in a specific way.
Here are the tables:
table: watchhistory
customerid | titleid | rating | date
------------+-----------+--------+------------
1488844 | tt0389605 | 3 | 2005-09-06
1181550 | tt0389605 | 3 | 2004-02-01
1227322 | tt0389605 | 4 | 2004-02-06
786312 | tt0389605 | 3 | 2004-11-16
525356 | tt0389605 | 2 | 2004-07-11
1009622 | tt0389605 | 1 | 2005-01-19
table: media
mediaid | directorid | title | genre | runtime | releasedate
-----------+------------+----------------+----------------------+---------+-------------
tt0090557 | nm0851724 | Round Midnight | [Drama, Music] | 133 | 1986
tt0312296 | nm0146385 | 1 Giant Leap | [Documentary, Music] | 155 | 2002
tt0078721 | nm0001175 | 10 | [Comedy, Romance] | 122 | 1979
tt2170245 | nm3593080 | 10 | [Thriller] | 76 | 2012
tt5282238 | nm6207118 | 10 | [Thriller] | 90 | 2015
tt0312297 | nm0302572 | 10 Attitudes | [Comedy, Drama] | 87 | 2001
I would like to make a table with the following columns:
title (from media) | Views#
I created this query to get the top 10 titleids, meaning the top 10 titles from watchhistory that appear in watchhistory the most times:
SELECT titleid, count(*) as Views FROM watchhistory GROUP BY titleid ORDER BY Views DESC limit 10;
titleid | views
------------+-------
tt7631348 | 1307
tt14627576 | 1065
tt8372506 | 1063
tt5793632 | 1056
tt1403008 | 1053
tt7825602 | 1051
tt6840954 | 1046
tt12780424 | 1042
tt7266106 | 1036
tt6539274 | 1035
The goal is to essentially replace this titleid column (from watchhistory) with the title (from media). I tried using joins between the watchhistory.titleid and media.mediaid with no luck.
What SQL query do I need to get this desired table?
Thanks in advance.
You need to INNER JOIN to your media table on mediaid:
SELECT m.title, count(wh.*) as Views
FROM watchhistory wh
INNER JOIN media m on m.mediaid = wh.titleid
GROUP BY m.mediaid
ORDER BY Views DESC LIMIT 10;
To see what the select and join are doing, you can simplify it:
SELECT m.*, wh.*
FROM watchhistory wh
INNER JOIN media m on m.mediaid = wh.titleid
The result will be a joined 'table' that has the two tables combined on the mediaid/titleid.
I have this query, it joins two tables and give me results of all the data under one a condition CATID is
'videography'
SELECT
pm_categories_images.Image,
pm_categories_images.FileURL,
pm_categories.catname,
pm_categories.`status`,
pm_categories.sortorder,
pm_categories.parentID,
pm_categories_images.CatID
FROM
pm_categories
LEFT JOIN pm_categories_images ON pm_categories_images.CatID = pm_categories.catID
where pm_categories_images.CatID IN (select catid from pm_categories where
parentID = (select catID from pm_categories where catname = 'Videography'))
Now this videography has a results like this
http://prntscr.com/gpkuyl
now i want to get 1 record for every catname
Without a MCVE and actual requirements on which image you want from the images table and a better understanding of why you need a left join when your where clause makes it behave like an inner... and why the where clause is so complex... ...I'm really unsure what the question is after... Here's a shot... and a DEMO:http://rextester.com/CRBN50943
Sample data expected results always a plus: I made my own and several assumptions
I interperted the question as: I would like a list of the categories along with a image having the earliest alphabetic value for each category.
SELECT
CI.Image,
CI.FileURL,
C.catname,
C.`status`,
C.sortorder,
C.parentID,
CI.CatID
FROM pm_categories C
INNER JOIN pm_categories_images CI
ON CI.CatID = C.catID
INNER JOIN (SELECT Min(Image) MI, catID FROM pm_categories_images group by CATID) Z
on CI.Image = Z.MI
and CI.CatID = Z.CatId
##WHERE C.catname = 'Videography'
Order by sortOrder
Giving us
+----+------------+-----------------------------------------------+-------------+--------+-----------+----------+-------+
| | Image | FileURL | catname | status | sortorder | parentID | CatID |
+----+------------+-----------------------------------------------+-------------+--------+-----------+----------+-------+
| 1 | guid1.jpg | https://drive.google.com/BusinessID/Postings/ | Real Estate | 1 | 1 | NULL | 1 |
| 2 | guid4.jpg | https://drive.google.com/BusinessID/Postings/ | commercial | 1 | 2 | NULL | 2 |
| 3 | guid6.jpg | https://drive.google.com/BusinessID/Postings/ | Videography | 1 | 3 | NULL | 3 |
| 4 | guid10.jpg | https://drive.google.com/BusinessID/Postings/ | Other | 1 | 4 | NULL | 4 |
| 5 | guid11.jpg | https://drive.google.com/BusinessID/Postings/ | LackingMCVE | 1 | 5 | NULL | 5 |
+----+------------+-----------------------------------------------+-------------+--------+-----------+----------+-------+
msyql query
SELECT id,student_user_id,MIN(start_time) FROM appoint_course
WHERE student_user_id IN(
931,2034,2068,2111,2115,2173,2181,2285,2500,2505,2507,
2518,2594,2596,2600,2608,2637,2652,2654
)
AND course_type=3 and disabled=0 GROUP BY student_user_id;
result
[query result]
+-------+-----------------+-----------------+
| id | student_user_id | MIN(start_time) |
+-------+-----------------+-----------------+
| 8356 | 931 | 1500351000 |
| 9205 | 2034 | 1501733400 |
| 9246 | 2068 | 1501649100 |
| 9755 | 2111 | 1502943000 |
| 9585 | 2115 | 1502595300 |
| 10820 | 2173 | 1503545700 |
| 9594 | 2181 | 1502852400 |
| 10324 | 2285 | 1502852400 |
| 11204 | 2500 | 1504839600 |
| 11152 | 2507 | 1504064100 |
| 12480 | 2594 | 1505707800 |
| 11521 | 2608 | 1504494000 |
| 11818 | 2652 | 1504753200 |
+-------+-----------------+-----------------+
but right start time is:
id: 9594
start_time: 1503284400
9594 right start_time is 1503284400 not 1502852400.In fact 1502852400 is a record of 9597
I do not know why.
In any other database your query would return an error, because id is not in the group by. The correct query is:
SELECT student_user_id, MIN(start_time)
FROM appoint_course
WHERE student_user_id IN (931,2034,2068,2111,2115,2173,2181,2285,2500,2505,2507,2518,2594,2596,2600,2608,2637,2652,2654) AND
course_type = 3 and disabled = 0
GROUP BY student_user_id;
In your case, adding a simple MIN(id) to the SELECT might work, assuming that ids increase with the start time.
More generally, you appear to want:
SELECT ac.*
FROM appoint_course ac
WHERE ac.student_user_id IN (931,2034,2068,2111,2115,2173,2181,2285,2500,2505,2507,2518,2594,2596,2600,2608,2637,2652,2654) AND
ac.course_type = 3 AND ac.disabled = 0 AND
ac.start_time = (SELECT MIN(ac2.start_time)
FROM appoint_course ac2
WHERE ac2.student_user_id = ac.student_user_id AND
ac2.course_type = ac.course_type AND
ac2.disabled = ac.disabled
);
No GROUP BY is necessary.
I should add that there is a MySQL hack that often works:
SELECT student_user_id, MIN(start_time),
SUBSTRING_INDEX(GROUP_CONCAT(id ORDER BY start_time), ',', 1) as id_at_min_start_time
FROM appoint_course
WHERE student_user_id IN (931,2034,2068,2111,2115,2173,2181,2285,2500,2505,2507,2518,2594,2596,2600,2608,2637,2652,2654) AND
course_type = 3 and disabled = 0
GROUP BY student_user_id;
This uses string manipulations and the GROUP_CONCAT() can overflow internal buffer sizes.
I'm having BookTable in database (with foregin hey LibID):
| BookID | BookName | BookPrice | LibID |
-------------------------------------------
| 1 | Book_1 | 200 | 1 |
| 2 | Book_2 | 100 | 1 |
| 3 | Book_3 | 300 | 2 |
| 4 | Book_4 | 150 | 4 |
and also LibraryTable:
| LibID | LibName | LibLocation |
-----------------------------------
| 1 | Lib_1 | Loc_1 |
| 2 | Lib_2 | Loc_2 |
| 3 | Lib_3 | Loc_3 |
| 4 | Lib_4 | Loc_4 |
I need to write SQL query that will return be the info about the library and number of books for that library:
| LibID | LibName | NumberOfBooks|
------------------------------------
| 1 | Lib_1 | 2 |
| 2 | Lib_2 | 1 |
| 3 | Lib_3 | 0 |
| 4 | Lib_4 | 1 |
It should be one SQL query, probably with nested queries or joins.. Not sure how the query should look like:
SELECT L.LibID AS LibID, L.LibName AS LibName, COUNT(B) AS NumberOfBooks
FROM LibraryTable L, BookTable B
WHERE L.LibID = B.LibID
Will that work?
No, this query will not work. COUNT aggregates data, so you must explicitely tell the DBMS for which group of data you want the count. In your case this is the library (you want one result record per library).
COUNT's parameter is a column, not a table, so change this to * (i.e. count records) or a certain column (e.g. LibID).
The join syntax you are using is valid, but deprecated. Use explicit joins instead. In your case an outer join would even show libraries that have no books at all, if such is possible.
select l.libid, l.libname, count(b.libid) as numberofbooks
from librarytable l
left outer join booktable b on b.libid = l.libid
group by l.libid;
You could also do all this without a join at all and get the book count in a subquery instead. Then you wouldn't have to aggregate. That's way simpler and more readable in my opinion.
select
l.libid,
l.libname,
(select count(*) booktable b where b.libid = l.libid) as numberofbooks
from librarytable l;
SELECT lt.LibID AS LibID, lt.LibName AS LibName, count(*) AS NumberOfBooks
FROM BookTable AS bt
LEFT JOIN LibraryTable AS lt ON bt.LibID = lt.LibID
GROUP BY bt.LibID
I have a Mysql table with the following data.
|ID | Date | BillNumber|BillMonth | Amount | Name |AccNum |
| 2 |2015-09-25| 454345 | 092015 | 135.00 |Andrew Good| 735976|
| 3 |2015-09-26| 356282 | 092015 | 142.00 |Peter Pan | 123489|
| 4 |2015-08-11| 312738 | 082015 | 162.00 |Andrew Good| 735976|
| 5 |2015-07-12| 287628 | 072015 | 220.67 |Andrew Good| 735976|
| 6 |2015-06-12| 100756 | 062015 | 556.34 |Andrew Good| 735976|
What I wanted to achieve is to retrieve the data of Andrew Good with AccNum 735976 for the BillMonth of 092015, provided that the user can entry any of his BillNumber(past/current).
If the reason that that row is of interest is because it is the latest of his rows, try:
select *
from tbl t
where name = ( select name
from tbl
where billnumber = 100756 -- can be any of his
)
and date = ( select max(date)
from tbl x
where x.name = t.name
)
(the billnumber can be any of his)