Denne fejlmeddelelse
skyldes typisk definitionen af dine kolonner og tabeller. Det betyder normalt, at der på hver side af et lighedstegn er forskellige sammenstillinger. Det, du skal gøre, er at vælge en og inkludere den beslutning i din forespørgsel.
Sorteringsproblemet her var i CROSS JOIN af @prev_value, som skulle bruge en eksplicit sortering for at blive brugt.
Jeg har også lidt ændret "row_number"-logikken til en enkelt krydssammenføjning og flyttet if-logikken til yderpunkterne af den valgte liste.
Nogle eksempeldata vises nedenfor. Eksempeldata er nødvendige for at teste forespørgsler med. Enhver, der forsøger at besvare dit spørgsmål med arbejdseksempler, har brug for data. Grunden til, at jeg medtager det her, er todelt.
- så du forstår ethvert resultat, jeg præsenterer
- så, at du i fremtiden forstår vigtigheden af at levere data, når du stiller et andet SQL-relateret spørgsmål. Det er ikke kun mere bekvemt for os, at du gør dette. Hvis spørgeren giver prøvedataene, vil spørgeren allerede forstå det - det vil ikke være en opfindelse af en fremmed, der har brugt noget af deres tid på at hjælpe.
Eksempel på data
Bemærk venligst, at nogle kolonner mangler i tabellerne, kun de kolonner, der er angivet i tabeldetaljerne, er inkluderet.
Denne eksempeldata har 5 kommentarer til et enkelt opslag (ingen likes registreres)
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, `date` datetime
) ;
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', 'ha lah lah', '2016-07-08 00:00:00'),
(789, 'a104', 'abcdefg', 'comment', 'hla lah lah', '2016-07-09 00:00:00') ;
[SQL Standard-adfærd:2 rækker pr. Post-forespørgsel]
Dette var min første forespørgsel, med nogle rettelser. Jeg ændrede kolonnerækkefølgen på udvalgslisten, så du nemt kan se nogle kommentarrelaterede data, når jeg præsenterer resultaterne. Læs venligst disse resultater, de er leveret, så du kan forstå, hvad forespørgslen vil gøre. Kolonner med # foran findes ikke i de eksempeldata, jeg arbejder med, af årsager, som jeg allerede har noteret.
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_likes
FROM Posts
INNER JOIN USERS ON Posts.id = 145
AND USERS.id = 145
LEFT 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 ON rcom.uuidPost = Posts.UUID
AND rcom.row_number <= 2
ORDER BY
posts.`date` DESC
;
Se en fungerende demonstration af denne forespørgsel på SQLFiddle
| id | uuid | uuidPost | commentText | date | date | id | username | profileImage | num_likes |
|-----|---------|----------|-------------|------------------------|---------------------------|-----|-----------------|--------------|-----------|
| 145 | abcdefg | abcdefg | hla lah lah | July, 09 2016 00:00:00 | October, 10 2016 00:00:00 | 145 | used_by_already | blah de blah | 0 |
| 145 | abcdefg | abcdefg | ha lah lah | July, 08 2016 00:00:00 | October, 10 2016 00:00:00 | 145 | used_by_already | blah de blah | 0 |
Der er 2 RÆKKER - som forventet. En række for den seneste kommentar, og en anden række for den næste seneste kommentar. Dette er normal adfærd for SQL, og indtil en kommentar blev tilføjet under dette svar, ville læsere af spørgsmålet antage, at denne normale adfærd ville være acceptabel.
Spørgsmålet mangler et klart formuleret "forventet resultat".
[Valgmulighed 1:En række pr. indlægsforespørgsel, med OP TIL 2 kommentarer, tilføjede kolonner]
I en kommentar nedenfor blev det afsløret, at du ikke ønskede 2 rækker pr. indlæg, og dette ville være en nem løsning. Det er på en måde nemt, MEN der er muligheder, og mulighederne er dikteret af brugeren i form af krav. HVIS spørgsmålet havde et "forventet resultat", ville vi vide, hvilken mulighed vi skulle vælge. Ikke desto mindre er her én mulighed
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_likes
FROM Posts
INNER JOIN USERS ON Posts.id = 145
AND USERS.id = 145
LEFT 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 ON rcom.uuidPost = Posts.UUID
AND rcom.row_number <= 2
GROUP 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
;
Se den anden forespørgsel, der arbejder på SQLFiddle
Resultater af forespørgsel 2 :
| id | uuid | Comment_one | Comment_two | date | id | username | profileImage | num_likes |
|-----|---------|-------------|-------------|---------------------------|-----|-----------------|--------------|-----------|
| 145 | abcdefg | hla lah lah | ha lah lah | October, 10 2016 00:00:00 | 145 | used_by_already | blah de blah | 0 |
** Mulighed 2, sammenkæd de seneste kommentarer til en enkelt kommasepareret liste **
SELECT
Posts.id
, Posts.uuid
, group_concat(rcom.commentText) Comments_two_concatenated
#, Posts.caption
#, Posts.path
, Posts.`date`
, USERS.id
, USERS.username
#, USERS.fullname
, USERS.profileImage
, COALESCE(A.LikeCNT, 0) num_likes
FROM Posts
INNER JOIN USERS ON Posts.id = 145
AND USERS.id = 145
LEFT 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 ON rcom.uuidPost = Posts.UUID
AND rcom.row_number <= 2
GROUP 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
Se denne tredje forespørgsel, der fungerer hos SQLFiddle
Resultater af forespørgsel 3 :
| id | uuid | Comments_two_concatenated | date | id | username | profileImage | num_likes |
|-----|---------|---------------------------|---------------------------|-----|-----------------|--------------|-----------|
| 145 | abcdefg | hla lah lah,ha lah lah | October, 10 2016 00:00:00 | 145 | used_by_already | blah de blah | 0 |
** Resumé **
Jeg har præsenteret 3 forespørgsler, hver viser kun de 2 seneste kommentarer, men hver forespørgsel gør det på en anden måde. Den første forespørgsel (standardadfærd) vil vise 2 rækker for hvert indlæg. Mulighed 2 tilføjer en kolonne, men fjerner den anden række. Mulighed 3 sammenkæder de 2 seneste kommentarer.
Bemærk venligst at:
- Spørgsmålet mangler tabeldefinitioner, der dækker alle kolonner
- Spørgsmålet mangler nogen prøvedata, hvilket gør det sværere for dig at forstå eventuelle resultater præsenteret her, men også sværere for os at udarbejde løsninger
- Spørgsmålet mangler også et endegyldigt "forventet resultat" (det ønskede output), og dette har ført til yderligere kompleksitet i besvarelsen
Jeg håber, at de yderligere angivne oplysninger vil være til nogen nytte, og at du efterhånden også ved, at det er normalt for SQL at præsentere data som flere rækker. Hvis du ikke ønsker den normale adfærd, bedes du være specifik om, hvad du virkelig ønsker i dit spørgsmål.
Efterskrift. For at inkludere endnu en underforespørgsel til "følger" kan du bruge en lignende underforespørgsel som den, du allerede har. Det kan tilføjes før eller efter denne underforespørgsel. Du kan også se det i brug på sqlfiddle her
LEFT JOIN (
SELECT
COUNT(*) FollowCNT
, IdOtherUser
FROM Activity
WHERE type = 'Follow'
GROUP BY
IdOtherUser
) F ON USERS.id = F.IdOtherUser
Mens tilføjelse af endnu en underforespørgsel kan løse dit ønske om mere information, kan den overordnede forespørgsel blive langsommere i forhold til væksten i dine data. Når du har sat dig fast på den funktionalitet, du virkelig har brug for, kan det være umagen værd at overveje, hvilke indekser du har brug for på disse borde. (Jeg tror, at du vil blive rådet til at bede om det råd separat, og hvis du gør det, skal du sørge for at inkludere 1. den fulde DDL for dine tabeller og 2. en forklarende plan for forespørgslen.)