Mysql
 sql >> база данни >  >> RDS >> Mysql

MYSQL Query - Вземете най-новия коментар, свързан с публикацията

Това съобщение за грешка

обикновено се дължи на дефиницията на вашите колони и таблици. Обикновено означава, че от двете страни на знака за равенство има различни сравнявания. Това, което трябва да направите, е да изберете един и да включите това решение в заявката си.

Проблемът със съпоставянето тук беше в CROSS JOIN на @prev_value, което изискваше изрично съпоставяне, за да се използва.

Също така леко промених логиката "row_number" на единично кръстосано свързване и преместих if логиката до крайностите на списъка за избор.

Някои примерни данни са показани по-долу. Необходими са примерни данни за тестване на заявки. Всеки, който се опитва да отговори на въпроса ви с работещи примери, ще се нуждае от данни. Причината да го включвам тук е двойна.

  1. така че да разберете всеки резултат, който представя
  2. така че в бъдеще, когато задавате друг въпрос, свързан със SQL, да разбирате важността на предоставянето на данни. За нас е не само по-удобно вие да направите това. Ако питащият предостави примерните данни, тогава питащият вече ще ги разбере - това няма да е изобретение на някой непознат, който е посветил част от времето си, за да помогне.

Примерни данни

Моля, имайте предвид, че някои колони липсват в таблиците, включени са само колоните, посочени в подробностите за таблицата.

Тези примерни данни имат 5 коментара срещу една публикация (не се записват харесвания)

CREATE TABLE Posts (`id` int, `uuid` varchar(7) collate utf8_unicode_ci,`imageLink` varchar(9) collate utf8_unicode_ci, `date` datetime ); INSERT INTO Posts(`id`, `uuid`, `imageLink`, `date`)VALUES(145, 'abcdefg', 'blah blah', '2016-10-10 00:00:00');CREATE TABLE USERS (`id` int, `username` varchar(15) collate utf8_unicode_ci, `profileImage` varchar(12) collate utf8_unicode_ci, `date` datetime); INSERT INTO USERS(`id`, `username`, `profileImage`, `date`)VALUES(145, 'used_by_already', 'blah de blah', '2014-01-03 00:00:00'); CREATE TABLE Activity(`id` int, `uuid` varchar(4) collate utf8_unicode_ci, `uuidPost` varchar(7) collate utf8_unicode_ci, `type` varchar(40) collate utf8_unicode_ci, `commentText` varchar(11) collate utf8_unicode_ci, ` дата` датачас); INSERT INTO Activity (`id`, `uuid`, `uuidPost`, `type`, `commentText`, `date`) VALUES(345, 'a100', 'abcdefg', 'comment', 'lah lha ha', '2016-07-05 00:00:00'),(456, 'a101', 'abcdefg', 'comment', 'lah lah lah', '2016-07-06 00:00:00'),( 567, 'a102', 'abcdefg', 'comment', 'lha lha ha', '2016-07-07 00:00:00'), (678, 'a103', 'abcdefg', 'comment', ' ха ла ла', '2016-07-08 00:00:00'), (789, 'a104', 'abcdefg', 'comment', 'hla lah lah', '2016-07-09 00:00:00'); 

[SQL Standard behavior:2 rows per Post query]

Това беше първоначалното ми запитване с някои корекции. Промених реда на колоните в списъка за избор, така че да видите лесно някои данни, свързани с коментари, когато представям резултатите. Моля, проучете тези резултати, които са предоставени, за да можете да разберете какво ще направи заявката. Колоните, предшествани от #, не съществуват в примерните данни, с които работя, поради причини, които вече отбелязах.

SELECT Posts.id, Posts.uuid, rcom.uuidPost, rcom.commentText, rcom.`date` commentDate #, Posts.caption #, Posts.path, Posts.`date`, USERS.id, USERS.username #, USERS.fullname, USERS.profileImage, COALESCE(A.LikeCNT, 0) num_likesFROM PostsINNER JOIN USERS ON Posts.id =145 И USERS.id =145LEFT JOIN ( SELECT COUNT(A.uuidPost) LikeCNT, A. UUIDPost FROM Activity A WHERE type ='like' GROUP BY A.UUIDPOST ) A ON A.UUIDPost =Posts.uuid LEFT JOIN ( SELECT @row_num :=IF(@prev_value=UUIDPOST,@row_num+1,1) as row_number , commentText , uuidPost , `date` , @prev_value :=UUIDPOST FROM Activity CROSS JOIN ( SELECT @row_num :=1, @prev_value :='' collate utf8_unicode_ci ) xy WHERE type ='comment' ORDER BY uuidPost , `date` DESC ) rcom НА r com.uuidPost =Posts.UUID И rcom.row_number <=2ORDER BY posts.`date` DESC;  

Вижте работеща демонстрация на тази заявка в SQLFiddle

Резултати :

<предварителен код>| ID | uuid | uuidPost | коментар Текст | дата | дата | ID | потребителско име | profileImage | брой_харесвания ||-----|---------|----------|-------------|------ ------------------|--------------------------|--- --|-----------------|--------------|-----------|| 145 | abcdefg | abcdefg | хла ла ла | 09 юли 2016 г. 00:00:00 | 10 октомври 2016 г. 00:00:00 | 145 | използван_от_вече | бла де бла | 0 || 145 | abcdefg | abcdefg | ха ла ла | 08 юли 2016 г. 00:00:00 | 10 октомври 2016 г. 00:00:00 | 145 | използван_от_вече | бла де бла | 0 |

Има 2 РЕДА - както се очаква. Един ред за най-скорошния коментар и още един ред за следващия най-скорошен коментар. Това е нормално поведение за SQL и докато не бъде добавен коментар под този отговор, читателите на въпроса ще приемат, че това нормално поведение ще бъде приемливо.

Във въпроса липсва ясно формулиран „очакван резултат“.

[Опция 1:Един ред на заявка за публикация, с ДО 2 коментара, добавени колони]

В коментар по-долу беше разкрито, че не искате 2 реда на публикация и това би било лесно решение. Е, донякъде е лесно, НО има опции и опциите се диктуват от потребителя под формата на изисквания. АКО въпросът имаше „очакван резултат“, тогава щяхме да знаем коя опция да изберем. Въпреки това ето една опция

SELECT Posts.id, Posts.uuid, max(case when rcom.row_number =1 then rcom.commentText end) Comment_one, max(case when rcom.row_number =2 then rcom.commentText end) Comment_two #, Posts.caption #, Posts.path, Posts.`date`, USERS.id, USERS.username #, USERS.fullname, USERS.profileImage, COALESCE(A.LikeCNT, 0) num_likesFROM PostsINNER JOIN USERS ON Posts.id =145 И USERS.id =145LEFT JOIN ( SELECT COUNT(A.uuidPost) LikeCNT, A.UUIDPost FROM Activity A WHERE type ='like' GROUP BY A.UUIDPOST ) A ON A.UUIDPost =Posts.uuid LEFT JOIN ( SELECT @row_num :=IF(@prev_value=UUIDPOST,@row_num+1,1) като row_number , commentText , uuidPost , `date` , @prev_value :=UUIDPOST FROM Activity CROSS JOIN ( SELECT @row_num :=1, @prev_value :='' collate utf8_unicode_ci ) xy тип WHERE ='comment' ORDER BY uuidPost , `date` DESC ) rcom ON rcom.uuidPost =Posts.UUID И rcom.row_number <=2GROUP BY Posts.id , Posts.uuid #, Posts.caption #, Posts.path , Posts. `date` , USERS.id , USERS.username #, USERS.fullname , USERS.profileImage , COALESCE(A.LikeCNT, 0)ORDER BY posts.`date` DESC; 

Вижте втората заявка, работеща в SQLFiddle

Резултати от заявка 2 :

<предварителен код>| ID | uuid | Коментар_един | Коментар_два | дата | ID | потребителско име | profileImage | брой_харесвания ||-----|---------|-------------|-------------|--- ------------------------|-----|-----------------|- -------------|-----------|| 145 | abcdefg | хла ла ла | ха ла ла | 10 октомври 2016 г. 00:00:00 | 145 | използван_от_вече | бла де бла | 0 |

** Вариант 2, обединете най-новите коментари в един списък, разделен със запетаи **

SELECT Posts.id, Posts.uuid, group_concat(rcom.commentText) Comments_two_concatenated #, Posts.caption #, Posts.path, Posts.`date`, USERS.id, USERS.username #, ПОТРЕБИТЕЛИ. fullname, USERS.profileImage, COALESCE(A.LikeCNT, 0) num_likesFROM PostsINNER JOIN USERS ON Posts.id =145 И USERS.id =145LEFT JOIN ( SELECT COUNT(A.uuidPost) LikeCNT, A.UUIDPost FROM Дейност A WHERE тип ='like' GROUP BY A.UUIDPOST ) A ON A.UUIDPost =Posts.uuid LEFT JOIN ( SELECT @row_num :=IF(@prev_value=UUIDPOST,@row_num+1,1) as row_number , commentText , uuidPost , `date` , @prev_value :=UUIDPOST FROM Activity CROSS JOIN ( SELECT @row_num :=1, @prev_value :='' collate utf8_unicode_ci ) xy WHERE type ='comment' ORDER BY uuidPost , `date` DESC ) rcom ON rcom.uuidP ost =Posts.UUID И rcom.row_number <=2GROUP BY Posts.id, Posts.uuid #, Posts.caption #, Posts.path, Posts.`date`, USERS.id, USERS.username #, USERS.fullname, USERS.profileImage , COALESCE(A.LikeCNT, 0)ORDER BY posts.`date` DESC  

Вижте тази трета заявка, работеща в SQLFiddle

Резултати от заявка 3 :

<предварителен код>| ID | uuid | Comments_two_concatenated | дата | ID | потребителско име | profileImage | брой_харесвания ||-----|---------|-------------------|--- ------------------------|-----|-----------------|- -------------|-----------|| 145 | abcdefg | хла ла ла,ха ла ла | 10 октомври 2016 г. 00:00:00 | 145 | използван_от_вече | бла де бла | 0 |

** Резюме **

Представих 3 заявки, всяка от които показва само 2-те най-нови коментара, но всяка заявка прави това по различен начин. Първата заявка (поведение по подразбиране) ще покаже 2 реда за всяка публикация. Вариант 2 добавя колона, но премахва втория ред. Опция 3 свързва двата най-скорошни коментара.

Моля, имайте предвид, че:

  • Във въпроса липсват дефиниции на таблици, покриващи всички колони
  • Въпросът не съдържа примерни данни, което прави по-трудно за вас да разберете резултатите, представени тук, но и по-трудно за нас да подготвим решения
  • Въпросът също така няма окончателен „очакван резултат“ (желания изход) и това доведе до допълнителна сложност при отговора

Надявам се, че допълнителната предоставена информация ще бъде от полза и че вече знаете, че е нормално SQL да представя данни като множество редове. Ако не искате това нормално поведение, моля, уточнете какво наистина искате във вашия въпрос.

Послепис. За да включите още една подзаявка за „следва“, можете да използвате подобна подзаявка на тази, която вече имате. Може да се добави преди или след тази подзаявка. Може също да го видите в употреба в sqlfiddle тук

LEFT JOIN ( SELECT COUNT(*) FollowCNT, IdOtherUser FROM Activity WHERE type ='Follow' GROUP BY IdOtherUser ) F ON USERS.id =F.IdOtherUser 

Въпреки че добавянето на друга подзаявка може да разреши желанието ви за повече информация, цялостната заявка може да се забави пропорционално на растежа на вашите данни. След като сте се спрели на функционалността, от която наистина се нуждаете, може да си струва да обмислите какви индекси са ви необходими на тези таблици. (Вярвам, че ще бъдете посъветвани да поискате този съвет отделно и ако го направите, уверете се, че сте включили 1. пълния DDL на вашите таблици и 2. план за обяснение на заявката.)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. mysql заявка за динамично конвертиране на данни от редове в колони

  2. Пълна система за регистрация на потребители, използваща PHP и MySQL база данни

  3. MySQL поддържа ли историческа дата (като 1200)?

  4. Променете името на колоната в MySQL

  5. #1136 - Броят на колоните не съвпада с броя на стойностите на ред 1