MySQL - Query not returning proper results - mysql

CREATE TABLE `swipes` (
`swp_id` bigint(20) NOT NULL,
`swp_by` bigint(20) NOT NULL,
`swp_to` bigint(20) NOT NULL,
`swp_type` varchar(255) NOT NULL,
`swp_status` enum('requested','accepted','declined') NOT NULL,
`swp_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `swipes` (`swp_id`, `swp_by`, `swp_to`, `swp_type`, `swp_status`, `swp_date`) VALUES
(1, 8, 11, 'top', 'accepted', '2020-04-18 20:48:45'),
(2, 1, 11, 'right', 'accepted', '2020-04-18 20:41:49'),
(3, 12, 1, 'right', 'accepted', '2020-04-18 20:41:49'),
(4, 13, 1, 'right', 'accepted', '2020-04-18 20:41:49'),
(5, 1, 14, 'right', 'accepted', '2020-04-18 20:41:49'),
(6, 1, 15, 'top', 'accepted', '2020-04-18 20:41:49');
CREATE TABLE `messages` (
`msg_id` bigint(20) NOT NULL,
`msg_from` bigint(20) NOT NULL,
`msg_to` bigint(20) NOT NULL,
`msg_message` longtext NOT NULL,
`msg_seen` enum('yes','no') NOT NULL DEFAULT 'no',
`msg_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `messages` (`msg_id`, `msg_from`, `msg_to`, `msg_message`, `msg_seen`, `msg_time`) VALUES
(1, 11, 1, 'How are you?', 'yes', '2020-04-14 21:01:05'),
(3, 1, 11, 'I am fine.. you?', 'no', '2020-04-14 20:54:07'),
(4, 1, 8, 'How are you?', 'yes', '2020-04-14 21:01:05'),
(5, 8, 1, 'I am good... You say?', 'yes', '2020-04-14 21:13:34'),
(6, 1, 11, 'Thik hun... Tum batao..', 'yes', '2020-04-14 21:16:05'),
(7, 11, 1, 'Okay', 'yes', '2020-04-16 09:16:39'),
(8, 8, 1, 'Yes, it\'s a good idea.', 'yes', '2020-04-16 09:16:39'),
(9, 1, 8, 'Thought so.. Would you like to join?', 'yes', '2020-04-16 09:23:39'),
(10, 8, 1, 'Are you there?', 'yes', '2020-04-23 11:57:39'),
(12, 8, 1, 'Would you like to join?', 'yes', '2020-04-23 10:42:27'),
(13, 1, 11, 'We will arrange things for you :)', 'yes', '2020-04-23 10:59:04');
Fiddle: DB FIDDLE
In the fiddle above my query is returning correct data but it seems to eliminate results when 1 is present in multiple records of swp_by in swipes table. At first I thought it was because of GROUP BY swipes.swp_by but I removed it and it seemed like it wasn't the issue so I placed it back. When you run the query you see that currently the query returns result for swp_id 2, 3 & 4 but not for 5 & 6. They are eliminated and it's because in swp_by 1 occurred in swp_id 2 once. I want the query to return the results for 5 & 6 as well.
Query
SELECT
swp_id,
swp_by,
swp_to,
msg_from,
msg_to,
msg_message,
GREATEST(MAX(msg_time), swipes.swp_date) AS msgdate,
COUNT(msg_id) AS msgcnt
FROM
swipes
LEFT JOIN
(SELECT
*
FROM
messages
ORDER BY msg_time DESC) messages ON ((messages.msg_from = swipes.swp_by
AND messages.msg_to = swipes.swp_to)
OR (messages.msg_from = swipes.swp_to
AND messages.msg_to = swipes.swp_by))
WHERE
(swipes.swp_by = 1 OR swipes.swp_to = 1)
AND swipes.swp_status = 'accepted'
GROUP BY swipes.swp_by
ORDER BY GREATEST(MAX(messages.msg_time),
MAX(swipes.swp_date)) DESC
What is this all about?
I am setting up a chatting system and users who are matched are able chat with each other. swipes stores the matches and messages are the transacted messages between the users. With this query I am trying to set up the home list of matched users to chat with where you tap/click a user and the chat box appears (will make that later). I thought just giving a brief about the project might help in understanding the problem.

I post my asnwer here the fiddle doesn't give the right link
no got it https://www.db-fiddle.com/f/2yKt6d5RWngXVYJKPGZL6m/2
SELECT
swp_id,
swp_by,
swp_to,
msg_from,
msg_to,
msg_message ,
GREATEST(MAX(msg_time), swipes.swp_date) AS msgdate,
COUNT(msg_id) AS msgcnt
FROM
swipes
LEFT JOIN
(SELECT
*
FROM
messages
ORDER BY msg_time DESC) messages
ON (messages.msg_from = swipes.swp_by
AND messages.msg_to = swipes.swp_to)
OR
(messages.msg_from = swipes.swp_to
AND messages.msg_to = swipes.swp_by)
WHERE
(swipes.swp_by = 1 OR swipes.swp_to = 1)
AND swipes.swp_status = 'accepted'
GROUP BY swipes.swp_by,swipes.swp_to
ORDER BY GREATEST(MAX(messages.msg_time),
MAX(swipes.swp_date)) DESC

Related

MySQL Attendance IN & OUT columns with correct times

I have a database for attendance, it works fine as long as the person does not work over 2 dates. I want to utilize IN and OUT system for records but I do not know how to do the final step, and what I saw on the forum does not work on MySQL or I am doing something wrong there.
This is my database and queries are under.
BTW Database is built using PHPmyadmin and MySQL Workbench.
CREATE TABLE `entries` (
`indexing` int(11) NOT NULL,
`emp_id` int(5) NOT NULL,
`Date` datetime DEFAULT current_timestamp() ) ;
INSERT INTO `entries` (`indexing`, `emp_id`, `Date`) VALUES
(61, 1, '2020-07-07 05:41:36'),
(62, 1, '2020-07-07 05:44:21'),
(63, 2, '2020-07-07 05:44:36'),
(64, 3, '2020-07-07 05:49:23'),
(65, 2, '2020-07-07 05:49:39'),
(66, 3, '2020-07-07 05:50:00'),
(67, 4, '2020-07-07 09:56:51'),
(68, 5, '2020-07-07 09:57:13'),
(69, 3, '2020-07-07 09:57:18'),
(70, 2, '2020-07-07 09:57:28'),
(71, 1, '2020-07-07 09:57:42'),
(72, 4, '2020-07-07 09:57:49'),
(73, 5, '2020-07-07 09:59:38'),
(74, 1, '2020-07-08 05:59:42'),
(75, 2, '2020-07-08 06:00:05'),
(76, 3, '2020-07-08 06:38:20'),
(77, 1, '2020-07-08 09:47:43'),
(78, 4, '2020-07-08 09:56:14'),
(79, 5, '2020-07-08 09:56:47'),
(80, 1, '2020-07-08 09:56:59'),
(81, 3, '2020-07-08 09:57:34'),
(82, 2, '2020-07-08 09:58:07'),
(83, 4, '2020-07-08 09:58:11'),
(84, 5, '2020-07-08 09:59:20'),
(85, 5, '2020-07-08 09:59:50'),
(86, 4, '2020-07-08 11:08:36'),
(87, 3, '2020-07-08 11:09:30');
CREATE TABLE `user` (
`emp_id` int(5) NOT NULL,
`Name` varchar(50) NOT NULL,
`company` set('First','second') NOT NULL DEFAULT 'First',
`department` set('Outbound','Inbound','UE','Returns','QC','Cleaner','Admin','IT
Technician','Supervisor','Manager') NOT NULL,
`driver` set('PPT','VNA','HLOP','CB','PPT VNA HLOP','PPT HLOP','PPT CB') DEFAULT NULL
) ;
INSERT INTO `user` (`emp_id`, `Name`, `company`, `department`, `driver`) VALUES
(1, 'Micinka', 'second', 'IT Technician', ''),
(2, 'Dusbica', 'First', 'IT Technician', ''),
(3, 'Klaudocka', 'First', 'Returns', ''),
(4, 'Patrycginis', 'First', 'Cleaner', ''),
(5, 'Stuistow', 'First', 'Cleaner', '');
--
ALTER TABLE `entries`
ADD PRIMARY KEY (`indexing`),
ADD KEY `emp_id` (`emp_id`);
--
-- Indexes for table `user`
--
ALTER TABLE `user`
ADD PRIMARY KEY (`emp_id`);
-- Constraints for table `entries`
--
ALTER TABLE `entries`
ADD CONSTRAINT `entries_ibfk_1` FOREIGN KEY (`emp_id`) REFERENCES `user` (`emp_id`) ON DELETE CASCADE;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=#OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=#OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=#OLD_COLLATION_CONNECTION */;
This are the Queries, and last one is how I would want the table look like but with IN and OUT times correct, now are both same.
select entries.emp_id, entries.Date, dense_rank() over (partition by entries.emp_id order by entries.indexing) % 2 AS 'IN and OUT' from entries;
drop table report_inout;
create view report_inout as select entries.emp_id, entries.Date,
CASE WHEN DENSE_RANK() OVER (PARTITION BY entries.emp_id ORDER BY entries.Date) % 2 = 0
THEN 'OUT' ELSE 'IN' END AS `IN and OUT`
FROM entries
ORDER BY
entries.indexing;
select date_format(report_inout.Date,'%d/%M/%Y') as `Date`,user.Name, time_format(report_inout.Date,'%H:%i:%s') as `IN`, time_format(report_inout.Date,'%H:%i:%s') as `OUT`,
user.company as Company,user.department as Department from report_inout
join user on user.emp_id = report_inout.emp_id
group by user.Name, report_inout.`In and Out`;
This are the results from my queries i posted.
emp_id;"Date";"IN and OUT"
1;"2020-07-07 05:41:36";"IN"
1;"2020-07-07 05:44:21";"OUT"
2;"2020-07-07 05:44:36";"IN"
3;"2020-07-07 05:49:23";"IN"
2;"2020-07-07 05:49:39";"OUT"
3;"2020-07-07 05:50:00";"OUT"
4;"2020-07-07 09:56:51";"IN"
5;"2020-07-07 09:57:13";"IN"
3;"2020-07-07 09:57:18";"IN"
2;"2020-07-07 09:57:28";"IN"
1;"2020-07-07 09:57:42";"IN"
4;"2020-07-07 09:57:49";"OUT"
5;"2020-07-07 09:59:38";"OUT"
1;"2020-07-08 05:59:42";"OUT"
2;"2020-07-08 06:00:05";"OUT"
3;"2020-07-08 06:38:20";"OUT"
1;"2020-07-08 09:47:43";"IN"
4;"2020-07-08 09:56:14";"IN"
5;"2020-07-08 09:56:47";"IN"
1;"2020-07-08 09:56:59";"OUT"
3;"2020-07-08 09:57:34";"IN"
2;"2020-07-08 09:58:07";"IN"
4;"2020-07-08 09:58:11";"OUT"
5;"2020-07-08 09:59:20";"OUT"
5;"2020-07-08 09:59:50";"IN"
and last query is this one, but it has always same time in IN and OUT
Date;"Name";"IN";"OUT";"Company";"Department"
08/July/2020;"Dusbica";"09:58:07";"09:58:07";"First";"IT Technician"
08/July/2020;"Dusbica";"06:00:05";"06:00:05";"First";"IT Technician"
08/July/2020;"Klaudocka";"09:57:34";"09:57:34";"First";"Returns"
08/July/2020;"Klaudocka";"11:09:30";"11:09:30";"First";"Returns"
08/July/2020;"Micinka";"09:47:43";"09:47:43";"second";"IT Technician"
08/July/2020;"Micinka";"09:56:59";"09:56:59";"second";"IT Technician"
08/July/2020;"Patrycginis";"11:08:36";"11:08:36";"First";"Cleaner"
08/July/2020;"Patrycginis";"09:58:11";"09:58:11";"First";"Cleaner"
08/July/2020;"Stuistow";"09:59:50";"09:59:50";"First";"Cleaner"
08/July/2020;"Stuistow";"09:59:20";"09:59:20";"First";"Cleaner"
Assuming that:
1st record for each separate emp_id is IN event
There is no lost events
WITH cte AS ( SELECT emp_id, `Date`,
ROW_NUMBER() OVER (PARTITION BY emp_id ORDER BY `Date`) - 1 rn
FROM entries )
SELECT t1.emp_id, user.name, t1.`Date` in_date, t2.`Date` out_date
FROM user
JOIN cte t1 ON user.emp_id = t1.emp_id
LEFT JOIN cte t2 ON t1.emp_id = t2.emp_id
AND t1.rn DIV 2 = t2.rn DIV 2
AND t2.rn MOD 2
WHERE NOT t1.rn MOD 2
ORDER BY emp_id, in_date;
fiddle
Idea.
We enumerate all rows for each employee separately starting with zero. So first IN is 0, first OUT is 1, 2nd IN is 2 and so on.
You can see that matched IN and OUT events will give the same result after integer divide their numbers by 2. And the reminder for IN will be 0 whereas for OUT it will be 1.
This is enough for correct joining.
Second copy of CTE table is joining using LEFT join because the last IN row may have no according OUT row - this means that the employee is now present at the object. And final row will contain NULL in out_date column in this case.

Complex SQL query issue (MYSQL Workbench 6.3)

I am having trouble figuring out how to write this query.
Let me explain the situation.
So, the question,
I need to display all the player names who have scored a score greater than 99, who have played matches in all the same grounds where a certain player (e.g. pid = 1) has played and has scored a score greater than 99.
(They could have played in other grounds besides the one pid = 1 has played, but the minimum requirement being they must have played in all the same grounds as him).
I have a database, which consist of 3 tables; player, ground, matches. And following data.
create database test1;
use test1;
CREATE TABLE `player` (
`pid` int(11) NOT NULL,
`pname` varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `ground` (
`gid` int(11) NOT NULL,
`gname` varchar(20) DEFAULT NULL,
`country` varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `matches` (
`pid` int(11) DEFAULT NULL,
`gid` int(11) DEFAULT NULL,
`score` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `player` ADD PRIMARY KEY (`pid`);
ALTER TABLE `ground` ADD PRIMARY KEY (`gid`);
ALTER TABLE `matches`
ADD KEY `gid` (`gid`),
ADD KEY `pid` (`pid`);
INSERT INTO `player` (`pid`, `pname`) VALUES
(1, 'afridi'),
(2, 'kohli'),
(3, 'imam'),
(4, 'fawad'),
(5, 'baven'),
(6, 'awais');
INSERT INTO `ground` (`gid`, `gname`, `country`) VALUES
(1, 'Qaddafi', 'PK'),
(2, 'National', 'PK'),
(3, 'Eden Garden', 'IND'),
(4, 'Lords', 'ENG'),
(5, 'MCG', 'AUS'),
(6, 'Arbab Nayyaz', 'PK');
INSERT INTO `matches` (`pid`, `gid`, `score`) VALUES
(1, 2, 23),
(1, 1, 111),
(2, 3, 107),
(2, 5, 103),
(1, 3, 117),
(1, 4, 55),
(1, 5, 101),
(1, 6, 44),
(2, 6, 103),
(2, 4, 103),
(2, 2, 117),
(2, 1, 103),
(4, 1, 77),
(3, 1, 13),
(5, 2, 22),
(3, 2, 101),
(3, 3, 101),
(5, 1, 101),
(5, 4, 101),
(5, 5, 101),
(6, 1, 101),
(6, 2, 101),
(6, 3, 101),
(6, 4, 101),
(6, 5, 101),
(6, 4, 101);
Relatively a simple database.
I've written the following query which displays the names of 4 players. It is displaying all the players who have played in the same grounds as pid = 1. How to display only those players which have played in all the same grounds as pid = 1.
select p.pname
from player p
join matches mn on mn.pid = p.pid
where (p.pid != 1) and (mn.score > 99) and exists (select m.gid from matches m where (m.pid = 1) and (mn.gid = m.gid))
group by pname;
According to the data provided in the tables,
Afridi (pid = 1) has scored century in the following grounds; 1, 3, and 5.
Respectively, players (pid) 2, 3, 5 ,6 have scored century in grounds = 1, 3, and 5.
These players have made centuries in other grounds as well but this query displays all players who have played in any of the 3 grounds.
The players could've played in other grounds as well, but the minimum requirement being that the players have to play in all the grounds; 1, 3, 5.
So, what I need is, only all those players, which have played in all of the same grounds, as in grounds; 1, 3, 5.
From observing the data in table matches we can see the players that have played in all the same grounds are only 2, being pid = 2, 6.
Any idea how to go about this?
I think this query should do what you want. It creates a table of grounds where the first player has played and made a century (g1), and joins that to the players who have also played at those grounds. If the number of different grounds that the other player has played at is the same as the number of different grounds that the first player has played at, they must have both played at the same set of grounds. Note there are a couple of places (in both subqueries) where you need to set the player id for comparison.
SELECT p.pname
FROM (SELECT gid, pid FROM matches WHERE pid=1 AND score >= 100) g1
LEFT JOIN matches m
ON m.gid = g1.gid AND m.pid != g1.pid
JOIN player p
ON p.pid = m.pid
GROUP BY m.pid
HAVING COUNT(DISTINCT m.gid) = (SELECT COUNT(DISTINCT gid) FROM matches WHERE pid=1 AND score >= 100)
ORDER BY m.pid
SQLFiddle Demo

Mysql query using group_concat and self referencing id in the table

Here is my table and sample data.
CREATE TABLE `sections` (
`section_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`parent_section_id` int(11) DEFAULT NULL,
PRIMARY KEY (`section_id`)
);
INSERT INTO `sections` (`section_id`, `name`, `parent_section_id`) VALUES
(1, 'City', NULL),
(2, 'Supplements', 4),
(3, 'News', 5),
(4, 'Sunday', 2),
(5, 'Monday', 2),
(6, 'Tuesday', 2),
(7, 'Wednesday', 2),
(8, 'Thursday', 2),
(9, 'Friday', 2),
(10, 'Saturday', 2),
(11, 'Home', 4),
(12, 'Games', 4),
(13, 'Sites', 5),
(14, 'Sports', 5),
(15, 'Cyber Space', 6);
parent_section_id is foreign key referencing to section_id in the same table which can have null if it doesn't belong to any other section.
How can I get the below output I have tried using group_concat function but it doesn't give the exact result. The parent_section_id is pointing to id from the same table. Should I use any other column to achieve the below output or use some other table to keep track of Sections which contains sub sections.
Please help me solve this problem or suggest any other approach
id, Name, SubSections
----------------------
1, 'City', null
2, 'Supplements', 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday'
3, 'News', null
4, 'Sunday', 'Homes,Games'
5, 'Monday','Sites,Sports'
6, 'Tuesday', 'Cyber Space'
7, 'Wednesday', null
8, 'Thursday', null
9, 'Friday', null
10, 'Saturday', null
11, 'Home', null
12, 'Games', null
13, 'Site', null
14, 'Sports', null
15, 'Cyber Space',null
Here is sql fiddle link http://sqlfiddle.com/#!9/e9767/2
Final Query
select s1.section_id, s1.name, group_concat(s2.name) as subsections,
(select name from sections where section_id = s1.parent_section_id) as 'parentname'
from sections s1
left join sections s2 on s1.section_id = s2.parent_section_id
group by s1.section_id;
You can get the result you want by using a (left) self-join on section_id = parent_section_id like so:
select s1.section_id, s1.name, group_concat(s2.name) as subsections
from sections s1
left join sections s2 on s1.section_id = s2.parent_section_id
group by s1.section_id;
Sample SQL Fiddle

Why operator LIMIT does not work correctly?

I wrote the next query SQL for getting last comments with re-comments:
SELECT c.*, ar.ArticleName, ar.idArticle, du.DetailToUsersName, du.DetailToUsersPhoto, COUNT(c.idCommentToArticle) AS CNT, CASE WHEN d.Count IS NULL THEN 0 ELSE d.Count END AS CountLikes
FROM commenttoarticle c
INNER JOIN (SELECT CommentToArticlePID FROM commenttoarticle
GROUP BY CommentToArticlePID
ORDER BY CommentToArticlePID LIMIT 3) AS articleComments
USING (CommentToArticlePID)
LEFT JOIN article ar ON c.CommentToArticleIdArticle = ar.idArticle
LEFT JOIN detailtousers du ON du.idDetailToUsers = c.CommentToArticleIdUser
LEFT JOIN `likes` d ON (d.IdNote = c.idCommentToArticle AND d.LikeType = 6)
WHERE c.CommentToArticleIdArticle = 11
GROUP BY c.idCommentToArticle
So, why operator LIMIT 3 in sub-query select does not work? Now this query shows all rows from table commenttoarticle
I seem that need do somethink like as:
SELECT...
FROM (select * from commenttoarticle commenttoarticle c INNER JOIN
(SELECT distinct(CommentToArticlePID)
FROM commenttoarticle b
ORDER BY CommentToArticlePID
LIMIT 2) AS commenttoarticle USING (CommentToArticlePID)) as c
LEFT JOIN article ar ON c.CommentToArticleIdArticle = ar.idArticle...
Dump table commenttoarticle:
CREATE TABLE IF NOT EXISTS `commenttoarticle` (
`idCommentToArticle` int(11) NOT NULL AUTO_INCREMENT,
`CommentToArticleTime` int(11) NOT NULL,
`CommentToArticleIdArticle` int(11) NOT NULL,
`CommentToArticleComment` text NOT NULL,
`CommentToArticleIdUser` int(11) NOT NULL,
`CommentToArticlePID` int(11) NOT NULL,
PRIMARY KEY (`idCommentToArticle`),
UNIQUE KEY `idCommentToArticle_UNIQUE` (`idCommentToArticle`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=59 ;
INSERT INTO `commenttoarticle` (`idCommentToArticle`, `CommentToArticleTime`, `CommentToArticleIdArticle`, `CommentToArticleComment`, `CommentToArticleIdUser`, `CommentToArticlePID`) VALUES
(29, 0, 11, 'продажам?\nИнтересует не мега-звезда, а именно предметный, руками умеющий продавать сам и помогающий выстраивать это бизнесам.', 459, 0),
(30, 0, 11, '2', 459, 0),
(31, 0, 11, '3', 459, 0),
(36, 0, 11, '3.1', 459, 31),
(37, 1413822798, 11, 'also facing that prob. on the plteform of win 7', 459, 29),
(38, 0, 11, ' here i dont have internet connection.. #Samint Sinha thanks ill check it out maybe tomorrow.', 459, 29),
(39, 0, 11, ' Select max id and you will have dhe last row returned', 459, 29),
(32, 0, 11, '4', 459, 0),
(44, 1414354324, 11, 'How to do', 456, 29),
(45, 1414354469, 11, 'sfsfsf', 456, 29),
(46, 1414354708, 11, 'dddd', 456, 29),
(47, 1414357761, 11, 'sfsfs', 456, 0),
(57, 1414370833, 39, 'kkkppppppp', 456, 0),
(49, 1414358233, 11, 'VSF\nSFSF', 456, 0),
(50, 1414359589, 11, 'How to do', 456, 0),
(51, 1414359660, 11, 'sfsfsdf', 456, 0),
(52, 1414361057, 11, 'SDFSF', 456, 0),
(53, 1414364023, 11, 'dsfdsjfsifmsi', 456, 0),
(54, 1414364031, 11, 'sdfdskjfnskf', 456, 52),
(55, 1414364034, 11, 'sdfdskjfnskf', 456, 52),
(56, 1414364044, 11, 'fndsdfnsofosfi', 456, 52),
(58, 1414370841, 39, 'dfgdfgdgdgdgdgdfgdgdfg', 456, 0);
Dump table article:
CREATE TABLE IF NOT EXISTS `article` (
`idArticle` int(11) NOT NULL AUTO_INCREMENT,
`ArticleName` varchar(255) NOT NULL,
`ArticleTime` int(11) NOT NULL,
`ArticleDescription` varchar(500) NOT NULL,
`ArticleText` text NOT NULL,
`ArticleToUserID` int(11) DEFAULT NULL,
`ArticleCategory` int(11) NOT NULL,
`ArticleView` int(11) NOT NULL,
`ArticleCountry` int(11) NOT NULL,
`ArticlePhoto` varchar(150) NOT NULL,
`ArticleCity` int(11) NOT NULL,
PRIMARY KEY (`idArticle`),
UNIQUE KEY `idArticle_UNIQUE` (`idArticle`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=50 ;
By constructing a self join on comments yuo're not limiting but multiply the result.
What you need is a single subquery on comments table
SELECT c.*, ar.ArticleName,
ar.idArticle, du.DetailToUsersName,
du.DetailToUsersPhoto, COALECSE(SUM(d.count), 0)
FROM
(SELECT *
FROM
commenttoarticle
WHERE
CommentToArticleIdArticle = 11
ORDER BY
CommentToArticlePID, idCommentToArticle DESC
LIMIT 3
) c
LEFT JOIN
article ar
ON c.CommentToArticleIdArticle = ar.idArticle
LEFT JOIN
detailtousers du
ON du.idDetailToUsers = c.CommentToArticleIdUser
LEFT JOIN
likes d
ON (d.IdNote = c.idCommentToArticle AND d.LikeType = 6)
GROUP BY
c.idCommentToArticle
I have made the assumption that a comment can have multiple entries in the likes table, otherwise the subquery and the group by is not necesarry.
The USING(column_list) clause names a list of columns that must exist in both tables.
reference: http://dev.mysql.com/doc/refman/5.0/en/join.html
CommentToArticlePID is not in your first table.
Also, what is the point of joining a single column? Yes, if you want to limit, this might be applicable, but then why us LIMIT?

multiple WHERE clauses on a joined table

I have a simple application that tracks diners and their favorite flavors and desserts. The records table is just the diner's name and ID, the mid table tracks the desserts and flavors (again by an ID linked to another table of values).
CREATE TABLE IF NOT EXISTS `records` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
INSERT INTO `records` (`id`, `name`) VALUES
(1, 'Jimmy Jones'),
(2, 'William Henry');
CREATE TABLE IF NOT EXISTS `mid` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`diner` int(11) NOT NULL,
`dessert` int(11) NOT NULL DEFAULT '0',
`flavor` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ;
INSERT INTO `mid` (`id`, `diner`, `dessert`, `flavor`) VALUES
(1, 1, 3, 0),
(2, 1, 2, 0),
(3, 1, 15, 0),
(4, 1, 0, 1),
(5, 2, 3, 0),
(6, 2, 6, 0),
(7, 2, 0, 4),
(8, 1, 34, 0),
(9, 2, 0, 4),
(10, 2, 0, 22);
I'm a little stumped by what should be a simple query-- I want to get all IDs from the records table where certain dessert or flavor requirements are met:
SELECT a.id
FROM records AS a
JOIN mid AS b ON a.id = b.diner
WHERE b.dessert IN (3,2,6)
AND b.flavor IN (4,22)
This query returns no rows, even though there are records that match the where clauses. I am pretty sure I'm missing something obvious with the JOIN but I've tried INNER, OUTER, LEFT and RIGHT with no success.
Can someone put me on the right track and explain what I'm missing?
Thanks
You seem to want diners that have the combinations. Here is one way:
select diner
from records
group by diner
having max(b.dessert = 3) = 1 and
max(b.dessert = 2) = 1 and
max(b.dessert = 6) = 1 and
max(b.flavor = 4) = 1 and
max(b.flavor = 22) = 1
This answers your comment:
select diner
from records
group by diner
having max(case when b.dessert in (2, 3, 6) then 1 esle 0 end) = 1 and
max(case when b.dessert in (4, 22) then 1 else 0 end) = 1
If you are just looking for the records in a that match the conditions, use:
select r.*, d.name
from records r join
diner d
on r.diner = d.id
where b.dessert IN (3,2,6) AND b.flavor IN (4,22)
If this is what you want, the join condition in your query is wrong (a.id should be a.diner).
You SQL statement is fine, but non of your sample records meet your condition, records that would match should look like this
dessert flavor
3 4
3 22
2 4
2 33
6 4
6 22
Non of your input record has any of these combinations
Your WHERE condition does not fit any record in the "mid" table.
There are no records that have dessert in (3, 2, 6) AND flavor in (4, 22), so the query (correctly)returns no result.
You don't have any records that match both where conditions.
( 1, 1, 3, 0) - Matches dessert IN (3,2,6)
( 2, 1, 2, 0) - Matches dessert IN (3,2,6)
( 3, 1, 15, 0)
( 4, 1, 0, 1)
( 5, 2, 3, 0) - Matches dessert IN (3,2,6)
( 6, 2, 6, 0) - Matches dessert IN (3,2,6)
( 7, 2, 0, 4) - Matches flavor IN (4,22)
( 8, 1, 34, 0)
( 9, 2, 0, 4) - Matches flavor IN (4,22)
(10, 2, 0, 22) - Matches flavor IN (4,22)
Perhaps you meant OR?
SELECT a.id
FROM records AS a
JOIN mid AS b ON a.id = b.diner
WHERE b.dessert IN (3,2,6)
OR b.flavor IN (4,22)
Should return 7 results.
Also, your thoughts on JOIN are a red herring. The difference between LEFT and RIGHT is just which table gets precedence when the join clause doesn't match records between them. The difference between INNER and OUTER is just what happens when there isn't a matching record between the two tables. Try this explanative article from coding horror for more details on joins (helpfully pointed out to me in a different SO question, heh).